간격이 다를 수 있는 중복 줄을 제거하되 #으로 시작하는 줄은 무시합니다.

간격이 다를 수 있는 중복 줄을 제거하되 #으로 시작하는 줄은 무시합니다.

이건 후속작이야이전 질문. 필드의 간격이 다른 경우에도 이 구문을 사용하여 중복 행을 제거합니다.

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

관련 정보