多くの行を含むファイルから3行目の後の2行を削除する方法は? [コピー]

多くの行を含むファイルから3行目の後の2行を削除する方法は? [コピー]

私が持っているように

1st line (keep)  
2nd line (keep)  
3rd line (keep)  
4rth lines (delete)  
5th (del)  
6th (keep)  
7nth (keep)  
8th lines  (keep)  
9th (del)  
10th (del)  
11th (keep)  
12th (keep)  
13th (keep)  
14th (del)  
15th (del)  

など....

答え1

努力する:

awk '(NR-1)%5<3' file

たとえば、

$ awk '(NR-1)%5<3' file
1st line (keep)
2nd line (keep)
3rd line (keep)
6th (keep)
7nth (keep)
8th lines (keep)
11th (keep)
12th (keep)
13th (keep)

どのように動作しますか?

このコマンドは、trueのすべての行を印刷するように指示(NR-1)%5<3します。 inは行番号で、最初の行数はです。ファイルの5行ごとに、このステートメントは最初の3行に適用されます。awk(NR-1)%5<3awkNR1

答え2

簡単なコマンドは次のとおりです。

awk '{if((NR-1) % 5<=2){print $0}}' file

5行の順序で最初の3行だけを印刷します。(NR-1)%5同様の出力を提供0 1 2 3 4し、最初の3行が2以下であるためです。だから、印刷するだけです。

内容を含むファイルがあります。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

出力は次のとおりです

1
2
3
6
7
8
11
12
13

または、コメントで提案されているように、次のものを使用できます。

awk '(NR - 1) % 5 <= 2' file

答え3

基本的に、awkでは「Fizz-Buzz」のようなものが欲しい。

awk '{ if (i++%5 < 3) print $0;}'

この作品を披露するために...

for x in 1 2 3 4 5 6 7 8 9 10 ; do echo $x; done |
awk '{ if (i++%5 < 3) print $0;}'

ファイル名が「mybigfile.csv」の場合、

awk '{ if (i++%5 < 3) print $0;}' < mybigfile.csv > mybigfile-123.csv

答え4

この問題はGNUを使用して解決できますsed

sed '4~5,5~5d' file

これはsedに標準のGNU固有の拡張を使用するため、macOSなどのBSD sedでは機能しません。ただし、GNU sedはmacOSを使用してインストールできますbrewが、gsedLinuxではGNU sedがデフォルトです。

これは、4行から5行に属さない5行のすべての行を印刷します。より明確な例:sed '3~10,6~10d'行3〜6、10行を削除して、10個のグループごとに1、2、7、8、9行を埋めます。

awk '(NR-1)%5<3'私のコンピュータでは、1〜200万の数字を含むファイルの場合は約0.6秒かかりますが、この回答のsedソリューションは約0.35秒かかります。 sed は通常より簡単なツールなので、より複雑ですが、すべての機能を備えた awk よりも高速に動作するため、これは合理的です。

関連情報