태그 보관물: sed

sed

텍스트 문자 사이의 여분의 공백을 삭제하는 스크립트 i c a l

모든 문자 뒤에 여분의 공간이 추가 된 텍스트가있는 텍스트 문서가 있습니다!

예:

T h e  b o o k  a l s o  h a s  a n  a n a l y t i c a l  p u r p o s e  w h i c h  i s  m o r e  i m p o r t a n t

시각적으로 :

T␣h␣e␣␣b␣o␣o␣k␣␣a␣l␣s␣o␣␣h␣a␣s␣␣a␣n␣␣a␣n␣a␣l␣y␣t␣i ␣c␣a␣l␣␣p␣u␣r␣p␣o␣s␣e␣␣w␣h␣i␣c␣h␣␣i␣s␣␣m␣o␣r␣e␣␣i␣ m␣p␣o␣r␣t␣a␣n␣t…

이 생길 것을 참고 추가 모든 편지 쓰기 후 공간, 그래서 연속 단어 사이에 두 개의 공간이있다.

여분의 공간을 얻 awk거나 sed삭제할 수있는 방법이 있습니까? (안타깝게도이 텍스트 문서는 방대하며 수동으로 처리하는 데 시간이 오래 걸립니다.) 
나는 일종의 텍스트 인식이 필요하기 때문에 간단한 bash 스크립트로 해결하는 것이 훨씬 더 복잡한 문제 일 것입니다.

이 문제에 어떻게 접근 할 수 있습니까?



답변

다음 정규식은 공백 문자열에서 첫 번째 공백을 제거합니다. 그 일을해야합니다.

s/ ( *)/\1/g

그래서 같은 :

perl -i -pe 's/ ( *)/\1/g' infile.txt

… infile.txt를 “고정”버전으로 대체합니다.


답변

wordsegment순수 파이썬 단어 세분화 NLP 패키지 인를 사용하십시오 .

$ pip install wordsegment
$ python2.7 -m wordsegment <<<"T h e b o o k a l s o h a s a n a n a l y t i c a l p u r p o s e w h i c h i s m o r e i m p o r t a n t"
the book also has an analytical purpose which is more important

답변

입력에 단어 사이에 이중 공백이 포함되어 있다는 사실을 기반으로 훨씬 간단한 솔루션이 있습니다. 이중 공백을 사용하지 않는 문자로 변경하고 공백을 제거한 후 사용하지 않은 문자를 공백으로 다시 변경하면됩니다.

echo "T h e  b o o k  a l s o  h a s  a n  a n a l y t i c a l  p u r p o s e  w h i c h  i s  m o r e  i m p o r t a n t  " | sed 's/  /\-/g;s/ //g;s/\-/ /g'

… 출력 :

이 책은 또한 더 중요한 분석 목적을 가지고 있습니다


답변

구조에 펄!

사전, 즉 한 줄에 한 단어 씩 나열된 파일이 필요합니다. 내 시스템에서는로 존재하며 /var/lib/dict/words비슷한 파일도 보았습니다 /usr/share/dict/british.

먼저, 사전의 모든 단어를 기억합니다. 그런 다음 한 줄씩 입력을 읽고 단어에 문자를 추가하려고합니다. 가능하다면 단어를 기억하고 나머지 줄을 분석해보십시오. 줄 끝에 도달하면 줄을 출력합니다.

#!/usr/bin/perl
use warnings;
use strict;
use feature qw{ say };

my $words = '/var/lib/dict/words';
my %word;

sub analyze {
    my ($chars, $words, $pos) = @_;
    if ($pos == @$chars) {
        $_[3] = 1;  # Found.
        say "@$words";
        return
    }
    for my $to ($pos .. $#$chars) {
        my $try = join q(), @$chars[ $pos .. $to ];
        if (exists $word{$try}) {
            analyze($chars, [ @$words, $try ], $to + 1, $_[3]);
        }
    }
}


open my $WORDS, '<', $words or die $!;
undef @word{ map { chomp; lc $_ } <$WORDS> };

while (<>) {
    my @chars = map lc, /\S/g;
    analyze(\@chars, [], 0, my $found = 0);
    warn "Unknown: $_" unless $found;
}

귀하의 입력에 대해서는 내 시스템에서 4092 개의 가능한 판독 값을 생성합니다.


답변

참고 :이 답변 (여기 다른 사람과 마찬가지로)은 단어가 구분되지 않은 이전 버전의 질문을 기반으로 합니다 . 최신 버전은 사소하게 대답 할 수 있습니다 .

다음과 같은 입력에서 :

T h e b o o k a l s o h a s a n a n a l y t i c a l p u r p o s e w h i c h i s m o r e i m p o r t a n t

시도해 볼 수 있습니다 :

 $ tr -d ' ' < file | grep -oiFf /usr/share/dict/words | paste -sd ' '
 The book also has ana na l y tic al purpose which ism ore important

왼쪽에서 오른쪽으로 처리하고 다음 단어 중에서 가장 긴 단어를 찾습니다.

분명히, 여기, 문장이 의미가 없기 때문에 가장 좋은 단어 선택은 아니지만 올바른 단어를 찾으려면 텍스트의 문법이나 의미를 이해하거나 최소한 통계를 이해할 수있는 도구가 필요합니다 어떤 단어가 함께 발견되어 가장 가능성이 높은 단어 집합을 찾을 수 있는지에 대한 정보. Lynn이 찾은 솔루션이 특수 라이브러리 인 것처럼 보입니다.


답변

Dewi Morgan의 버전과 유사하지만 sed가 있습니다.

$ echo "f o o  t h e  b a r" | sed -r "s/[ ]{1}([^ ]{1})/\1/g"
foo the bar

답변

비록 그것이 Perl one-liner로 수행 될 수는 있지만, 작은 C 파서는 매우 빠르며 또한 매우 작습니다 (그리고 희망적으로 매우 정확합니다).

#include <stdio.h>
#include <stdlib.h>

int main()
{
  char c1 = '\0', c2 = '\0', tmp_c;

  c1 = fgetc(stdin);
  for (;;) {
    if (c1 == EOF) {
      break;
    }
    c2 = fgetc(stdin);
    if (c2 == EOF) {
      if (c1 != ' ') {
        fputc(c1, stdout);
      }
      break;
    }
    if (c1 == c2 && c1 == ' ') {
      tmp_c = fgetc(stdin);
      if (tmp_c != EOF) {
        if (tmp_c != '\n') {
          ungetc(tmp_c, stdin);
          fputc(' ', stdout);
        } else {
          ungetc(tmp_c, stdin);
        }
      } else {
        break;
      }
    } else if (c1 != ' ') {
      fputc(c1, stdout);
    }
    c1 = c2;
  }
  exit(EXIT_SUCCESS);
}

로 컴파일

gcc-4.9 -O3 -g3  -W -Wall -Wextra -std=c11 lilcparser.c -o lilcparser

(프로그램은 9kb 미만입니다)

다음과 같은 파이프에서 사용하십시오.

echo "T h e  b o o k  a l s o  h a s  a n  a n a l y t i c a l  p u r p o s e  w h i c h  i s  m o r e  i m p o r t a n t  " | ./lilcparser