通常のファイルのみ「sed -i」に渡す

通常のファイルのみ「sed -i」に渡す

sed私はGNU sed 4.2.2を使用していますが、検索した後に何らかの理由で奇妙に動作する理由はわかりません。

次の内容を含むディレクトリがあります。

foofile.txt
barfile.txt
bazfile.txt
config/

ケース1

sed -i 's/foo/bar/g' *.txt

これは私が期待どおりに機能します。 3つの汎用ファイルのすべての「foo」を「bar」に置き換えます。

ケース2

sed -i 's/foo/bar/g' *
sed: couldn't edit config: not a regular file

barfile.txtでは、「foo」を「bar」に変更しますが、そうbazfile.txtではありませんfoofile.txt。アルファベット順に展開されたファイルのリストを見て、エラーが発生したときに終了すると*します。エラーを無視してファイル処理を続行するconfig/方法はありますか?sed

ケース3

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がなぜこれを行うのかを尋ねています。

find . -maxdepth 1 -type f -exec sed -i 's/foo/bar/g' {} \;

答え1

  • ケース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
    

答え2

これは通常の動作です。どちらの場合も…persedで終了します。error code 4info sed

4
     An I/O error, or a serious processing error during runtime,
     GNU 'sed' aborted immediately.

どちらの場合も、メッセージは説明を必要としません。何が不明であるかはわかりませんが、記録のために:最初はディレクトリを編集できないためエラーが発生し、2番目は編集できないため文句を言い、ファイルが必要ですstdin(たとえば、古いリダイレクトを削除するなど$file)。
正しい方法findあなたが指摘したように、globを使用してこれを行う-exec ...
には、ループを使用して実行する前に入力が通常のファイルであるかどうかをテストする必要がありますsed。または、ユーザーの場合は、zsh単に次のことができます。

sed -i 's/foo/bar/g' *(.)

関連情報