2009-07-24 11 views
3
bash-3.2$ sed -i.bakkk -e "s#/sa/#/he/#g" .* 
sed: .: in-place editing only works for regular files 

フォルダ内のすべてのドットファイルに/ sa/with/he /を置き換えようとしています。どうすればそれを稼働させることができますか?Odd Sedエラーメッセージ

答えて

7

使用find -type fは名前.*に一致するだけファイルを見つけるとディレクトリ...を除外します。 -maxdepth 1findがサブディレクトリに再帰するのを防ぎます。次に-execを使用してsedコマンドを実行し、{}プレースホルダを使用して、ファイル名がどこにあるかをfindに伝えます。それも変なファイル・スペースを含む名前、あるいは改行でうまくいくよう-execを使用して

find . -type f -maxdepth 1 -name '.*' -exec sed -i.bakkk -e "s#/sa/#/he/#g" {} + 

はい、"foo bar\nfile"は有効なファイル名である—バッククォートを使用したりxargs以上が望ましいです。優秀な言及は、等しく安全なfind -print0 | xargs -0

find . -type f -maxdepth 1 -name '.*' -print0 | xargs -0 sed -i.bakkk -e "s#/sa/#/he/#g" 

に行きます。それは、ファイル名が最後に行くコマンド(おそらく99%)のコマンドでしか機能しないので、もう少し冗長で柔軟性がありません。

+0

+最後に?それは ";"と同じですか? ? –

+1

";"ファイルごとにコマンドを実行するので、10個のファイルに対して10個のsedsが実行されます。 "+"はファイルのすべて*を一度渡して実行し、10個のファイルに対して1 sedにします。 –

+0

「rm。*」などのコマンドは、ドットファイルを削除するのが安全でないことを意味しますか?あなたが好むべきである:find。 -name "。*" -exec rm '{}' \; ? –

1

グロブパターン.*には、特別なディレクトリ...が含まれています。これはおそらくあなたのパターンに含めることを意味しませんでした。これは、すべてのディレクトリを無視すべきで

sed -i.bakkk -e "s#/sa/#/he/#g" `find .* -type f -maxdepth 0 -print` 

(例えば、.elmファイル、.pine:

sed -i.bakkk -e "s$/sa/#/he/#g" $(ls -d .* | grep -v '^\.\|\.\.$') 
+2

+1。 find/xargsをおすすめします:find。 -type f -maxdepth 1 -name '。*' | xargs sed ... – pilcrow

2

はこの1つを試してみてください:私はそれらを除外するためのエレガントな方法を考えることはできませんので、ここで無粋な方法です、.mozilla)だけでなく。と私は他の解決策をキャッチしないと思う。