오늘이 사용 사례가 발생했습니다. 그것은 첫눈에 간단하게 보이지만, 주변에 바이올린을 켜고 sort
, uniq
, sed
과 awk
는 사소하다고 밝혔다.
어떻게 모두 삭제할 수 있습니다 쌍의 중복 라인을? 다시 말해, 주어진 행에 짝수의 복제본이 있으면 모두 삭제하십시오. 홀수의 중복 행이 있으면 하나를 제외하고 모두 삭제하십시오. (정렬 된 입력을 가정 할 수 있습니다.)
깨끗하고 우아한 솔루션이 바람직합니다.
입력 예 :
a
a
a
b
b
c
c
c
c
d
d
d
d
d
e
출력 예 :
a
d
e
답변
sed
이 질문을 게시 한 지 얼마되지 않아 답을 찾았습니다 . sed
지금까지 아무도 사용 하지 않았습니다.
sed '$!N;/^\(.*\)\n\1$/d;P;D'
보다 일반적인 문제 (3 개 또는 4 개 또는 5 개 세트에서 행을 삭제하는 것은 어떻습니까)로 약간의 장난은 다음과 같은 확장 가능한 솔루션을 제공했습니다.
sed -e ':top' -e '$!{/\n/!{N;b top' -e '};};/^\(.*\)\n\1$/d;P;D' temp
세 줄의 선을 제거하기 위해 확장 :
sed -e ':top' -e '$!{/\n.*\n/!{N;b top' -e '};};/^\(.*\)\n\1\n\1$/d;P;D' temp
또는 쿼드 라인을 제거하려면 :
sed -e ':top' -e '$!{/\n.*\n.*\n/!{N;b top' -e '};};/^\(.*\)\n\1\n\1\n\1$/d;P;D' temp
sed
복제본을 검사하기 위해 실제 줄 수보다 더 많은 메모리 저장 공간이 필요하지 않은 스트림에서 실제로 작동 할 수있는 기능인 대부분의 다른 옵션에 비해 추가적인 이점이 있습니다.
으로 cuonglm는 의견에서 지적 제대로 멀티 바이트 문자가 포함 된 줄을 제거하는 C 로켈은 피할 실패에 필요한 설정. 따라서 위의 명령은 다음과 같습니다.
LC_ALL=C sed '$!N;/^\(.*\)\n\1$/d;P;D' temp
LC_ALL=C sed -e ':top' -e '$!{/\n/!{N;b top' -e '};};/^\(.*\)\n\1$/d;P;D' temp
LC_ALL=C sed -e ':top' -e '$!{/\n.*\n/!{N;b top' -e '};};/^\(.*\)\n\1\n\1$/d;P;D' temp
# Etc.
답변
매우 우아하지는 않지만 내가 생각해 낼 수있는만큼 간단합니다.
uniq -c input | awk '{if ($1 % 2 == 1) { print substr($0, 9) }}'
substr ()은 uniq
출력을 잘라냅니다 . 9,999,999 개가 넘는 행이 복제 될 때까지 작동합니다 (이 경우 uniq의 출력이 9자를 넘을 수 있음).
답변
아래이 awk
스크립트를 사용해보십시오 :
#!/usr/bin/awk -f
{
if ((NR!=1) && (previous!=$0) && (count%2==1)) {
print previous;
count=0;
}
previous=$0;
count++;
}
END {
if (count%2==1) {
print previous;
}
}
lines.txt
파일이 정렬되어 있다고 가정합니다 .
시험:
$ chmod +x script.awk
$ ./script.awk lines.txt
a
d
e
답변
로 pcregrep
주어진 샘플에 대한 :
pcregrep -Mv '(.)\n\1$' file
또는 더 일반적인 방법으로 :
pcregrep -Mv '(^.*)\n\1$' file
답변
입력이 정렬 된 경우 :
perl -0pe 'while(s/^(.*)\n\1\n//m){}'
답변
python
예를 들어 python
2.7 이상 에서 이것을 좋아 합니다.
from itertools import groupby
with open('input') as f:
for k, g in groupby(f):
if len(list(g)) % 2:
print(k),
답변
내가 각 레코드의 해시를 사용하여 awk에 대해 선택한 질문을 이해 했으므로이 경우 RS = \ n이라고 가정하지만 다른 종류의 배열을 고려하도록 변경 될 수 있습니다. 매개 변수 또는 작은 대화 상자를 사용하여 홀수 대신 짝수 번 반복하십시오. 모든 줄은 해시로 사용되며 그 수가 증가합니다. 파일 끝에서 배열이 스캔되고 모든 짝수의 레코드를 인쇄합니다. 확인하기 위해 개수를 포함하고 있지만 a [x]를 제거하면 문제를 해결할 수 있습니다.
HTH
카운트 라인 코드
#!/usr/bin/nawk -f
{a[$0]++}
END{for (x in a) if (a[x]%2!=0) print x,a[x] }
샘플 데이터 :
a
One Sunny Day
a
a
b
my best friend
my best friend
b
c
c
c
One Sunny Day
c
d
my best friend
my best friend
d
d
d
One Sunny Day
d
e
x
k
j
my best friend
my best friend
샘플 실행 :
countlines feed.txt
j 1
k 1
x 1
a 3
One Sunny Day 3
d 5
e 1