여러 파일에서 특정 줄을 제거하는 방법을 찾고 있는데 해당 줄이 해당 파일에 여러 번 나타나는 경우에만 가능합니다. 다른 행은 중복되더라도 유지되어야 합니다.
예를 들어, 이와 같은 파일의 경우 중복된 파일을 제거하고 싶습니다.AAA
AAA
BBB
AAA
BBB
CCC
되어야 한다
AAA
BBB
BBB
CCC
를 사용해야 할 것 같은데, sed
명령어를 어떻게 작성해야 할지 모르겠습니다.
답변1
GNU 사용 sed
:
sed '0,/^AAA$/b;//d'
즉, 첫 번째 행(행 0(첫 번째 행 이전에도)과 첫 번째 일치 행 (첫 번째 행일 수 있음)) 까지 모든 것을 통과( b
a 처럼 분기 )한 다음 나머지 줄에서 모든 항목을 삭제합니다. (빈 패턴은 마지막 패턴을 재사용합니다)continue
AAA
/^AAA$/
AAA
//
sed
Address에는 GNU가 필요합니다 ( 동일 표현식에서 명령 뒤에 다른 명령을 포함할 0
수 있는 기능도 있지만 이는 두 표현식을 사용하여 다른 구현에서 쉽게 해결할 수 있음 ).b
-e
그리고 awk
:
awk '$0 != "AAA" || !n++'
(또는 정규식 패턴의 경우 awk '!/^AAA$/ || !n++'
:)
약어:
awk '! (&0 == "AAA" && count > 0) {print; count++}'
답변2
Stéphane Chazelas의 awk
솔루션아름답다:
awk '!/AAA/ || !n++' file.in
이는 다음과 같이 요약될 수 있습니다.
awk '$0 !~ pattern || !n++' pattern="$pattern" file.in
$pattern
일부 정규식을 포함하는 특정 쉘 변수의 경우.
백슬래시를 포함하는 경우 $pattern
이스케이프 처리( \\
)해야 합니다. 또는 다음을 사용할 수 있습니다.
P="$pattern" awk '$0 !~ ENVIRON["P"] || !n++' file.in
답변3
라인이 나타날 때마다 버퍼를 교환하고 패턴 공간에 동일한 라인이 포함되어 있으면 삭제하고, 그렇지 않으면 보유된 버퍼에서 라인을 검색하십시오.
sed -e '/^AAA$/{x;//d;g' -e'}' infile
또는
sed '/^AAA$/{
x
//d
g
}' infile