sedを使用してテキストファイルから特定の行番号を削除しますか?


235

ファイルから1つ以上の特定の行番号を削除したい。sedを使用してこれをどのように実行しますか?


1
あなたが望むもののより具体的な例を挙げられますか?削除する行をどのように決定しますか?
Mark Byers、2010年

たぶん、stackoverflow.com / questions / 13272717 /… も参照して、逆に適用してください(連想配列にキーがない場合は印刷してください)。
tripleee

回答:


374

5行目から10行目と12行目を削除する場合:

sed -e '5,10d;12d' file

これにより、結果が画面に出力されます。結果を同じファイルに保存する場合:

sed -i.bak -e '5,10d;12d' file

これにより、ファイルがにバックアップされfile.bak、指定された行が削除されます。

注:行番号は1から始まります。ファイルの最初の行は0ではなく1です。


32
すべてのunixが「-i」でnusedしているわけではありません。ファイルを消去する「sed cmd file> file」にフォールバックするミスを犯さないでください。
2010年

4
最後の行まで5行目を削除したい場合はどうすればよいですか?
ユルゲンポール

14
@WearetheWorldsed -e '5,$d' file
ブライアンキャンベル

1
@BrianCampbell特定の行だけを削除するにはどうすればよいですか?
Kanagavelu Sugumar 14

14
@KanagaveluSugumar sed -e '5d' file。構文は次のとおりです<address><command>。where <address>はのような単一の行5またはのような行の範囲のいずれか5,10であり、コマンドdは指定された行を削除します。アドレスは、正規表現、または$ファイルの最終行を示すドル記号にすることもできます。
ブライアンキャンベル

50

特定の単一行とその行番号を削除するには、

sed -i '33d' file

これにより、33行目の行が削除され、更新されたファイルが保存されます。


1
私の場合、「sed」は間違った行を削除しました。したがって、私はこのアプローチを使用しますsed -i '0,/<TARGET>/{/<NEW_VALUE>/d;}' '<SOME_FILE_NAME>'。ありがとう!
エドゥアルドルシオ2018年

ここでも同じですが、ループを作成しましたが、奇妙なことに一部のファイルで正しい行が失われましたが、一部のファイルでも他の行が1つ失われているため、問題の原因がわかりません。(GNU / Linux bash4.2)以下のawkコマンドはループ内で
正常に機能しました

行のリストから削除する場合は、sort -rの使用に十分注意してください。そうしないと、最初のsedによって他のすべての行番号が変更されます!...
Konchog

ループ内で削除された間違った行についてコメントするには、必ず最大の行番号から始めてください。そうしないと、削除された行ごとに行番号がオフセットされます…
Skippy le Grand Gourou

25

そしてawkも

awk 'NR!~/^(5|10|25)$/' file

2
注意:そのawkラインは、sedバリアント(OS-XとUbuntu Linuxの間)よりも確実に機能しました
Jay Taylor

3
これはファイル内の何も削除しないことに注意してください。これらの行なしでファイルをstdoutに出力するだけです。したがって、出力を一時ファイルにリダイレクトし、一時ファイルを移動して元のファイルを置き換える必要もあります。
mivk


6

これは非常に頻繁にアンチパターンの症状です。行番号を生成したツールは、すぐに行を削除するツールに置き換えることができます。例えば;

grep -nh error logfile | cut -d: -f1 | deletelines logfile

deletelinesあなたが必要としていると想像しているユーティリティはどこですか)は同じです

grep -v error logfile

そうは言っても、本当にこのタスクを実行する必要がある場合はsed、行番号のファイルから単純なスクリプトを生成できます。ユーモラスに(しかし、少し混乱するかもしれませんが)これはで行うことができますsed

sed 's%$%d%' linenumbers

これは、行番号のファイルを1行に1つずつ受け入れ、標準出力で、同じ行番号をdそれぞれの後に追加して生成します。これは有効なsedスクリプトであり、ファイルに保存したり、(一部のプラットフォームでは)別のsedインスタンスにパイプしたりできます。

sed 's%$%d%' linenumbers | sed -f - logfile

いくつかのプラットフォームでは、sed -fオプションの引数を理解していない-あなたは、一時ファイルにスクリプトをリダイレクトし、作業が完了したときに、それをクリーンアップ、または多分との孤独なダッシュ交換する必要がありますので、標準入力を意味する/dev/stdinか、/proc/$pid/fd/1お使いのOS(またはシェルの場合を)それがあります。

いつものように、標準出力に結果を生成する代わり-iに、-fオプションの前に追加してsed、ターゲットファイルを編集することができます。* BSDishプラットフォーム(OSXを含む)では、明示的な引数-iも指定する必要があります。一般的なイディオムは、空の引数を提供することです。-i ''


「アンチパターンの症状」には全く同意できません。マークアップベースのファイルタイプ(XMLやJSONなど)では、有効なファイルになるために末尾に特定の行が必要です。その場合、それらの行を削除し、ファイルに追加したいものを入れてから、それらの行を再度追加するのが最も合理的なアプローチです。なぜなら、行をすぐに間に置くのは、はるかに手間がかかるためです。 sedのような余分なツールをできるだけ避けたいという潜在的な欲求。
エゴールハンス

どんなシナリオを想像しているのかよくわかりません。これ正当なアプローチであるシナリオがありますが、私が見たケースの大部分は、私の最初の例が示すことを多かれ少なかれ正確に行う初心者です。(おそらく、それらはいくつかの本当に低レベルの言語から来ており、asmまたはCで入力する必要があるため、分子レベルを超えて問題を分割するために使用されます。)
tripleee

XMLまたはJSONから行番号で内容を削除すると、まったく危険ではないにしても、非常に壊れやすくなります。
tripleee 2018

私が基本的に言っていることは、そのようなファイルの作成者は、ドキュメントの最後に何があるべきかを知っているということです(つまり、JSONの最後の数行の右中括弧/角括弧のセット、または正確にXMLの終了タグ)。このようなドキュメントを拡張する最も簡単な方法は、1)最後の数行を削除する、2)新しいコンテンツを追加する、3)最後の数行を再度追加することです。このようにして、文書の途中で行を追加する方法を見つける必要なしに、文書が拡張される前と後の両方で有効になります。
エゴールハンス

1
これまでのところ、これは、多数の行に対する適切な解決策(つまり、ファイルによって提供される)を持つ唯一の答えです。序文も理にかなっています。それはより多くの賛成に値する。ところで、行を削除するのではなく印刷したい場合pd、の代わりにをオプションとともに使用します-n(なし-nでは機能せず、また機能し!dません)。
Skippy le Grand Gourou

2

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に現在のブロック内の行番号を書き込みます。(下記参照)
  • ||and &&は、論理演算子ORおよびANDです。
  • 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      |
+-----+------+----------+------------+


2
あなたが狂気を誘う名前に生きる方法に感心します。
Jukka Dahlbom、2015
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.