ファイルから1つ以上の特定の行番号を削除したい。どのように私はこれをsedを使ってしますか?
5行目から10行目および12行目を削除したい場合は、次のようにします。
sed -e '5,10d;12d' file
これにより結果が画面に表示されます。結果を同じファイルに保存したい場合は、
sed -i.bak -e '5,10d;12d' file
これはファイルをfile.bak
までバックアップし、与えられた行を削除します。
注:行番号は1から始まります。ファイルの最初の行は0ではなく1です。
sed -i '33d' fileによって、特定の単一行をその行番号とともに削除できます。
これは33行番号の行を削除し、更新されたファイルを保存します。
そしてawkも
awk 'NR!~/^(5|10|25)$/' file
$ cat foo
1
2
3
4
5
$ sed -e '2d;4d' foo
1
3
5
$
これは非常に頻繁にアンチパターンの症状です。行番号を生成したツールは、すぐに行を削除するツールに置き換えることができます。例えば;
grep -nh error logfile | cut -d: -f1 | deletelines logfile
(ここでdeletelines
は、あなたが必要と考えているユーティリティです)と同じです
grep -v error logfile
そうは言っても、本当にこのタスクを実行する必要がある場合は、行番号のファイルから簡単なsed
スクリプトを生成できます。ユーモラスに(ただし、少し混乱するかもしれませんが)sed
でこれを行うことができます。
sed 's%$%d%' linenumbers
これは、行ごとに1つの行番号のファイルを受け入れ、標準出力で、それぞれの後にd
が追加された同じ行番号を生成します。これは有効なsed
スクリプトであり、ファイルに保存したり、(一部のプラットフォームでは)別のsed
インスタンスにパイプしたりできます。
sed 's%$%d%' linenumbers | sed -f - logfile
一部のプラットフォームでは、sed -f
は標準引数を意味するオプション引数-
を理解しないため、スクリプトを一時ファイルにリダイレクトし、完了したらクリーンアップするか、またはOS(またはシェル)にある場合は、/dev/stdin
または/proc/$pid/fd/1
を含むダッシュのみ。
いつものように、-i
オプションの前に-f
を追加して、標準出力で結果を生成する代わりに、sed
でターゲットファイルを編集できます。 * BSDishプラットフォーム(OSXを含む)では、-i
への明示的な引数も指定する必要があります。一般的なイディオムは、空の引数を指定することです。 -i ''
。
Awkを使った一般化を提案したい。
ファイルが固定サイズのブロックで作成され、削除する行がブロックごとに繰り返される場合、awkはそのようにしてうまく機能します。
awk '{nl=((NR-1)%2000)+1; if ( (nl<714) || ((nl>1025)&&(nl<1029)) ) print $0}'
OriginFile.dat > MyOutputCuttedFile.dat
この例では、ブロックのサイズは2000で、[1..713]と[1026..1029]の行を印刷します。
NR
は、現在の行番号を格納するためにawkによって使用される変数です。%
は、2つの整数の除算の余り(または法)を与えます。nl=((NR-1)%BLOCKSIZE)+1
ここで変数nl現在のブロック内の行番号を書きます。 (下記参照)||
および&&
は論理演算子またはおよびそして。print $0
は全行を書き込みますWhy ((NR-1)%BLOCKSIZE)+1:
(NR-1) We need a shift of one because 1%3=1, 2%3=2, but 3%3=0.
+1 We add again 1 because we want to restore the desired order.
+-----+------+----------+------------+
| NR | NR%3 | (NR-1)%3 | (NR-1)%3+1 |
+-----+------+----------+------------+
| 1 | 1 | 0 | 1 |
| 2 | 2 | 1 | 2 |
| 3 | 0 | 2 | 3 |
| 4 | 1 | 0 | 1 |
+-----+------+----------+------------+