이건 후속작이야이전 질문. 필드의 간격이 다른 경우에도 이 구문을 사용하여 중복 행을 제거합니다.
awk '{$1=$1};!NF||!seen[$0]++' /tmp/fstab
이제 로 시작하는 줄을 제외하고 싶습니다 #
. 그래서 저는 이 구문을 사용합니다.
awk '/^#/ || "'!'"'{$1=$1};!NF||!seen[$0]++' /tmp/fstab
-bash: !: event not found
내 문법에 무슨 문제가 있나요?
답변1
어때요?
awk '!NF||$1~/^#/ {print; next} {$1=$1} !seen[$0]++' /tmp/fstab
그러면 빈 줄이나 첫 번째 필드가 시작되는 줄이 즉시 인쇄되고 #
실행을 건너뛰어 추가 코드가 무시됩니다. 다른 모든 줄은 아직 발견되지 않은 한 재구성되어 인쇄됩니다.
$1~/^#/
전체 줄에 일치 항목을 적용하는 대신(즉, 간단히) if를 확인하는 이유 는 앞에 공백이 있는 주석 줄 /^#/
도 잡을 수 있도록 하기 위함입니다 . #
맨페이지에서는 fstab
주석 줄 자격을 갖추기 위해 다음 사항을 요구하지만,첫 번째문자는 이어야 하며 #
@StephenKitt가 지적했듯이 Linux 구현에서는 libmount
선행 공백을 건너뛰고 한 줄을 주석으로 허용합니다.비어 있지 않은 첫 번째캐릭터는 #
.
답변2
bash
불평하고 (아님 awk
) 주위에 작은 따옴표가 있기 때문에 !
문제는 분명합니다. 종료하는 명령 블록입니다 awk
.
awk '{$1=$1} /^#/ || !seen[$0]++' file
즉, 먼저 작업을 수행한 다음 확인하십시오. 단점: 주석의 공백도 제거/줄이지만 그러한 중복 항목은 제거하지 않습니다. 먼저 줄을 버퍼링하여 이를 방지하세요.
awk '{a=$0 ; $1=$1} /^#/ || !seen[$0]++ {print a}' file
입력하다:
#comment
duplicate line
#comment
duplicate line
not duplicate
not duplicate 2
duplicate line
#comment2
#comment2
#comment 3
#comment 3
출력(첫 번째 코드)
#comment
duplicate line
#comment
not duplicate
not duplicate 2
#comment2
#comment2
#comment 3
#comment 3
출력(두 번째 코드)
#comment
duplicate line
#comment
not duplicate
not duplicate 2
#comment2
#comment2
#comment 3
#comment 3
답변3
GNU sed
확장 정규식 모드 켜짐-E
sed -Ee '
# print empty|blank|comment lines
/^\s*(#|$)/b
s/\s+/ /g;s/^ | $//g;G; # squeeze whitespace n append previous unique lines
/^([^\n]*)\n(.*\n)?\1(\n|$)/d; # delete if seen
P;h;d; # print seen first time then update seen list
' file