반복되는 시작으로 텍스트 줄 연결

반복되는 시작으로 텍스트 줄 연결

다음 형식의 줄을 포함하는 긴 텍스트 파일(stardict-editor의 탭 파일)이 있습니다.

word1  some text
word1  some other text
word2  more text
word3  even more

그리고 그것을 다음으로 변환하고 싶습니다.

word1  some text<br>some other text
word2  more text
word3  even more

이는 동일한 단어(파일이 정렬됨)로 시작하는 후속 행이 단일 행(여기서는 delimited 로 정의됨 <br>)으로 병합되어야 함을 의미합니다. 시작이 동일한 줄이 두 번 이상 나타날 수도 있습니다. 단어와 정의를 구분하는 문자는 탭 문자이며 각 줄에서 고유합니다. word1, word2, word3는 물론 내가 미리 알지 못하는 임의의 콘텐츠(탭과 줄 바꿈 제외)에 대한 자리 표시자입니다.

이 작업을 수행하기 위해 더 긴 Perl 코드 조각을 생각할 수 있지만 Perl이나 명령줄에 간단한 솔루션이 있는지 알고 싶습니다. 어떤 아이디어가 있나요?

답변1

perl -p0E 'while(s/^((.+?)\t.*)\n\2\t/$1<br>/gm){}' 

(6년 된 내 노트북에서는 150만 행의 23MB 사전을 처리하는 데 2초가 걸립니다.)

답변2

이는 표준 절차입니다.awk

awk '
{
  k=$2
  for (i=3;i<=NF;i++)
    k=k " " $i
  if (! a[$1])
    a[$1]=k
  else
    a[$1]=a[$1] "<br>" k
}
END{
  for (i in a)
    print i "\t" a[i]
}' long.text.file

파일이 줄의 첫 번째 단어로 정렬되면 스크립트가 더 간단해질 수 있습니다.

awk '
{
  if($1==k)
    printf("%s","<br>")
  else {
    if(NR!=1)
      print ""
    printf("%s\t",$1)
  }
  for(i=2;i<NF;i++)
    printf("%s ",$i)
  printf("%s",$NF)
  k=$1
}
END{
print ""
}' long.text.file

그렇지 않으면bash

unset n
while read -r word definition
do
    if [ "$last" = "$word" ]
    then
        printf "<br>%s" "$definition"
    else 
        if [ "$n" ]
        then
            echo
        else
            n=1
        fi
        printf "%s\t%s" "$word" "$definition"
        last="$word"
     fi
done < long.text.file
echo

답변3

이것은 실제로 표준입니다 awk. 작업 데이터를 변경하지 않는 깔끔한 솔루션은 다음과 같습니다.

awk 'BEGIN { FS="\t" }
     $1!=key { if (key!="") print out ; key=$1 ; out=$0 ; next }
     { out=out"<br>"$2 }
     END { print out }'

답변4

파이썬에서는:

import sys

def join(file_name, join_text):
    prefix = None
    current_line = ''
    for line in open(file_name):
        if line and line[-1] == '\n':
            line = line[:-1]
        try:
            first_word, rest = line.split('\t', 1)
        except:
            first_word = None  # empty line or one without tab
            rest = line
        if first_word == prefix:
            current_line += join_text + rest
        else:
            if current_line:
                print current_line
            current_line = line
            prefix = first_word

    if current_line:  # do the last line(s)
        print current_line


join(sys.argv[2], sys.argv[1])

<br>이를 위해서는 프로그램의 첫 번째 인수로 구분 기호( )가 필요 하고 두 번째 인수로 파일 이름이 필요합니다.

관련 정보