답변:
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자를 넘을 수 있음).
uniq -c input | awk '{if ($1 %2 == 1) { print $2 } }'
했고 똑같이 잘 작동하는 것처럼 보였다. substr
버전이 더 좋은 이유는 무엇입니까?
$2
를 $NF
보다 견고 하게 인쇄하는 루프가 아니 겠습니까?
foo bar
.
입력이 정렬 된 경우 :
perl -0pe 'while(s/^(.*)\n\1\n//m){}'
pineapple\napple\ncoconut
출력은 pinecoconut
입니다.
\n
대신 $
주어진 /m
수식,하지만 나는 것을 깨달았 사용하여 $
삭제 라인 대신에 빈 줄을 떠날 것이다. 지금은 좋아 보인다; 소음이 추가되어 잘못된 버전을 제거했습니다. :)
내가 각 레코드의 해시를 사용하여 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
awk
코드이지만 불행히도 awk
연관 배열은 전혀 순서가 없으며 순서를 유지하지도 않습니다.
sort
.
!=0
하는 방법에 의해 암시 될 수 있음을 주목할 가치가 있습니다.awk
awk '{a[$0]++}END{for(x in a)if(a[x]%2)print x}'
쉘 구조를 사용하여
uniq -c file | while read a b; do if (( $a & 1 == 1 )); then echo $b; fi done
$b
)으로 구분됩니다.
재미있는 퍼즐!
펄에서 :
#! /usr/bin/env perl
use strict;
use warnings;
my $prev;
while (<>) {
$prev = $_, next unless defined $prev; # prime the pump
if ($prev ne $_) {
print $prev;
$prev = $_; # first half of a new pair
}
else {
undef $prev; # discard and unprime the pump
}
}
print $prev if defined $prev; # possible trailing odd line
하스켈에서 말 그대로 :
main :: IO ()
main = interact removePairs
where removePairs = unlines . go . lines
go [] = []
go [a] = [a]
go (a:b:rest)
| a == b = go rest
| otherwise = a : go (b:rest)
하스켈에서 간절히 :
import Data.List (group)
main = interact $ unlines . map head . filter (odd . length) . group . lines
버전 : 나는 "구분 기호"를 사용하여 내부 루프를 단순화합니다 (첫 번째 줄이 아니라고 __unlikely_beginning__
가정하고 텍스트가 줄로 끝나지 않는다고 가정합니다 : __unlikely_ending__
및 입력 줄 끝에 특수 구분 기호 줄을 추가하십시오. 알고리즘은 다음을 모두 가정 할 수 있습니다.)
{ cat INPUTFILE_or_just_- ; echo "__unlikely_ending__" ; } | awk '
BEGIN {mem="__unlikely_beginning__"; occured=0; }
($0 == mem) { occured++ ; next }
( occured%2 ) { print mem ;}
{ mem=$0; occured=1; }
'
그래서 :
C
, 그렇지 않으면 멀티 바이트 로케일에서 해당 로케일의 유효하지 않은 문자로 인해 명령이 실패 할 수 있습니다.