XからYまでの行にのみ表示される重複行を削除し、ファイルを所定の位置に変更するにはどうすればよいですか?
たとえば、10行から20行の重複行のみを削除したい場合です。
答え1
GNUを使用するawk
(4.1.0以降のinplace
拡張1):
gawk -i /usr/share/awk/inplace.awk '
NR >= 10 && NR <= 20 {
if ($0 in seen) next
seen[$0]
}
{print}' ./file
または以下を使用してperl
:
perl -ni -e 'print if $. < 10 or $. > 20 or !$seen{$_}++' ./file
複数のファイル処理:
gawk -i /usr/share/awk/inplace.awk '
BEGINFILE{delete seen}
FNR >= 10 && FNR <= 20 {
if ($0 in seen) next
seen[$0]
}
{print}' ./*.txt
または以下を使用してperl
:
perl -ni -e '
print if $. < 10 or $. > 20 or !$seen{$_}++;
if (eof) {close ARGV; undef %seen}' ./*.txt
^使用しないでください-i inplace
現在の作業ディレクトリから最初に拡張機能をgawk
ロードしようとすると、誰かがそのディレクトリにマルウェアを植えた可能性があります。システムに付属の拡張プログラムのパスは異なる場合があります。出力を参照してください。inplace
inplace
inplace.awk
inplace
gawk
gawk 'BEGIN{print ENVIRON["AWKPATH"]}'
答え2
awk
あなたの友達です
awk '{
if(NR>=10 && NR<=20)
{
if($0 in record){
next
}else{
print;
record[$0];
}
}
else{
print
}
}' file > temp && mv temp file
答え3
OPが10〜20行内の重複行を削除する必要がある場合:
sed -i '
:a; 10,19!b; N; s/\(^\|\n\)\([^\n]*\)\n\(\(.\+\n\|\)\2$\)/\1\3/; ba
' file1 file2 ...
答え4
Perlベースの回答に適用されたのと同じトリックを使用してAwkコードを短縮することもでき、結果的に小さくてきれいになります。
awk 'NR < 10 || NR > 20 || !seen[$0]++'
^ ^ ^ ^
| | | |
| \__________\___________\______ no sigil noise
|
\_ no options here to remember
(unless we want that Gawk inplace semantics)
範囲は10行に制限されており、GNU Awkにはとにかく大きな整数があるため、カウンタはオーバーフローしません。