중복된 정보가 포함된 텍스트 필드

중복된 정보가 포함된 텍스트 필드

텍스트 필드가 있는 탭으로 구분된 데이터 파일이 있는데, 그 중 일부는 세미콜론으로 구분되어 반복되는 정보를 가지고 있습니다.

2000;2000
05/19/2016;05/19/2016
foo;foo

중복된 부분을 어떻게 sed제거할 수 있나요? 세미콜론은 다른 필드에 자주 나타나므로 세미콜론 양쪽에 있는 문자열을 검색하고 탭 문자, 즉 \t$1;$1\t( \t탭을 의미)로 묶인 다음 $1세미콜론과 중복이 없는 문자열 로 바꿔야 할 것 같습니다. 인스턴스 사이트. 다른 텍스트 구문 분석 명령을 사용할 수 있습니다.

답변1

파일에서 다음을 사용하십시오 tabbed.input(공백 없음, 연속된 모든 공백은 탭임).

abc     bd      c       2000;2000       d       2;00;2;01
e       05/19/2016;05/19/2016   foo;foo f       g

다음 Python 프로그램:

def cleaned(f):
    length = len(f)
    if (length % 2) == 0:
        return f  # even number of characters in field, middle one never ';'
    half_way = length // 2
    if f[half_way] != ';':
        return f
    before, after = f[:half_way], f[half_way+1:]
    if before == after:
        return before
    return f

with open('tabbed.input') as fp:
    for line in fp:
        fields = line[:-1].split('\t')
        cleaned_fields = [cleaned(f) for f in fields]
        print('\t'.join(cleaned_fields))

결과는 다음과 같습니다:

012345670123456701234567012345670123456701234567
abc     bd      c       2000    d       2;00;2;01
e       05/19/2016      foo     f       g

짝수 문자를 테스트하고 필드 중간에 " "를 포함시켜 ;중복 데이터에 " "가 포함 된 ;경우에도 작동합니다.

답변2

POSIX적으로:

sed -e 's/\([^;][^;]*\);\1/\1/g' <file

다음을 사용할 수도 있습니다.

sed -E 's/([^;]+);\1/\1/g' <file

이는 GNU 및 BSD sed에서 지원되며 다음 POSIX 표준이 될 것입니다.

답변3

그리고 perl:

perl -F'\t' -e 'map {s/(.+);$1/$1/} @F; print join("\t",@F)'

해당 sed솔루션과 달리 이 솔루션은 각 필드를 개별적으로 처리하므로 필드 전체에서 중복 항목을 감지하고 제거할 가능성을 방지합니다(예 foo;<TAB>foo: TAB 및 두 번째 필드는 foo솔루션에 의해 제거되지만 솔루션 sed에서는 제거되지 않음 perl). 입력 데이터에 따라 실제 사용에는 문제가 되지 않을 수도 있습니다.

다음 버전에서는 필드(예: a;b;a;b;a;b--> a;b)에서 여러 중복 항목을 제거합니다.

perl -F'\t' -e 'map {while(/(.+);$1/) {s/(.+);$1/$1/g}} @F;print join("\t",@F)'

참고: 이러한 가정은 최신 버전에 대한 것으로 perl, 이는 및 을 -F의미합니다 . 이전 버전이 있는 경우 다음을 사용하세요.-a-nperl -F'\t' -ane '...'

관련 정보