[bash] sedで指定したファイルパスを含む行を削除する方法


はじめに

sedの行削除コマンド「d」の直前に「/pattern/」を指定することで、指定したパターンにマッチする文字列を含む行を削除することができる。

たとえば、下記のテキストファイルの行を削除したい場合

sample.txt

$ cat sample.txt
sampletext1
sampletext2
・・・

sampletext1の行を削除するとすると下記を実行する

$ sed '/sampletext1/d' sample.txt
sampletext2
・・・

指定したsampletext1の行が削除されます。

基本的なsedの使い方については、さまざまなサイトで紹介されていますのでここでは省略します。

本記事では、実際にハマった「ファイルパスを含む行の削除」についての方法の備忘録となります。

 

 

ファイルパスを含む行の削除

ファイルパスは「/tmp/work/…」のように「/」が含まれているため、普通に記載するだけでは
うまく処理できません。

実際に下記のようなデータが記載されているファイルに対して普通に指定した場合の実行例です

sample.txt

$ cat sample.txt
/tmp/test1.txt
/tmp/test2.txt
/tmp/test3.txt
/tmp/test4.txt
/tmp/test5.txt
$ sed '//tmp/test1.txt/d' sample.txt
sed: `mp/text1.txt' へジャンプするためのラベルが見つかりません

エラーがでて削除ができませんでした。

では、どのようにするかというと下記のようにします

$ sed '\|/tmp/test1.txt|d' sample.txt
/tmp/test2.txt
/tmp/test3.txt
/tmp/test4.txt
/tmp/test5.txt

問題なく削除できました。

しかし、ファイルの中身自体は削除されていないので、下記で上書きして保存してあげましょう

$ sed -i '\|/tmp/test1.txt|d' sample.txt

すると、実際にファイルからも削除されます。

ファイルパスが変数の場合も同じように利用できます

filepath=/tmp/test1.txt
sed -i "\|${filepath}|d" sample.txt

変数のファイルパスを置換してマッチングする方法もあります。

filepath=/tmp/text1.txt
rpl=`echo ${filepath} | sed s,/,\\\\\/,g`
sed -i -e "/${rpl}/d" sample.txt

「\」がかなり多いですが、ファイルパスの置換ではよく使うので覚えておいて良いかと思います。

 

 

さいごに

実際にCSVファイルなどの入出力の際などえで利用するケースがあるかと思います。

ファイルパスを含む行の処理は結構ハマりましたので、ぜひご活用ください。