私はGNU sed 4.2.2を使用していますが、検索後にsed
がいくつかの状況で奇妙に動作する理由を見つけることができません:
次のディレクトリがあります:
foofile.txt
barfile.txt
bazfile.txt
config/
sed -i 's/foo/bar/g' *.txt
これは期待どおりに機能します。これは、3つの通常ファイル内のすべての「foo」を「bar」に置き換えます。
sed -i 's/foo/bar/g' *
sed: couldn't edit config: not a regular file
barfile.txt
とbazfile.txt
では「foo」を「bar」に置き換えますが、foofile.txt
では置き換えません。私はそれが*
からアルファベット順に展開されたファイルのリストを通過し、config/
にヒットするとエラーになって終了すると想定しています。 sed
でエラーを無視してファイルの処理を続行する方法はありますか?
for file in $(find . -maxdepth 1 -type f); do sed -i 's/foo/bar/g' <"$file"; done
sed: no input files
sed: no input files
sed: no input files
誰かがsed
がなぜこれを行うのか説明してもらえますか?入力ファイルが与えられたときに入力ファイルがないと表示されるのはなぜですか?
以下を使用できることはわかっていますが、sedがこのように動作する理由を尋ねています。この1つの使用例を解決する方法ではありません。
find . -maxdepth 1 -type f -exec sed -i 's/foo/bar/g' {} \;
これは正常な動作です。どちらの場合でも、sed
はerror code 4
ごとにinfo sed
...で終了します。
4
An I/O error, or a serious processing error during runtime,
GNU 'sed' aborted immediately.
どちらの場合も、メッセージは自明です。何が不明確なのかはわかりませんが、記録についてです。ディレクトリを編集できないために最初にエラーが発生し、stdin
を直接編集できないためにエラーが発生した場合は、ファイルが必要です(つまり、リダイレクトを削除します) $file
より前)find
を使用してこれを行う適切な方法は、お気付きのとおり、-exec ...
を使用することです
グロブを使用する場合、sed
を実行する前に、ループを使用して、入力が通常のファイルであるかどうかをテストする必要があります。または、zsh
ユーザーの場合は、次のようにすることができます。
sed -i 's/foo/bar/g' *(.)
ケース2:
find
でそのディレクトリを避けてください:
sed -i 's/foo/bar/g' `find . -maxdepth 1 -type f`
ケース3:
問題は<"$file"
ループ内では、ファイルをストリームに変換するため、sed
はファイル名を見ることはありません。削除してください<
:
for file in $(find . -maxdepth 1 -type f); do sed -i 's/foo/bar/g' "$file"; done