間隔が異なる可能性がある重複行は削除されますが、#で始まる行は無視されます。

間隔が異なる可能性がある重複行は削除されますが、#で始まる行は無視されます。

これはフォローアップです。前の質問。フィールドの間隔が異なる場合でも、この構文を使用して重複行を削除します。

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実装は先行スペースをスキップし、コメントを1行で許可し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

出力(2番目のコード)

#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

関連情報