私が直面しているこの問題を解決するために、SO)に記載されているさまざまな解決策を試しました。
すべてのファイルを再帰的に検索し、特定のテキストを変更したいと思います。
これは私がWindowsのcygwinで使用しているコマンドです
find . -not -path \*.hg\* -exec sed -i 's/FCLP1025/FCLP1080/g' {} \;
私が得る結果は
sed: couldn't edit ./xxx/yyy/filename: not a regular file
ここで足りないものはありますか?
find
は、すべてのファイルとすべてのディレクトリのリストを返します。実際に文字列を含むファイルを検索するように検索を制限する必要があります。追加してみることができます:
find -type f ... # Doesn't return directories
find -iname "*.txt" ... # returns only files ending in '.txt' (case insensitive)
または、本当に凝ったものにしたい場合は、grepを使用して、実際に文字列を含むファイルに対してのみsedを実行してみてください。
grep -l -r 'FCLP1025' | xargs sed -i 's/FCLP1025/FCLP1080/g'
grepの-r
は再帰的に検索し、-l
は一致するファイルのファイル名のみをリストします。次に、xargs
はstdinを使用し、それを次のコマンドの引数として追加します。これは、{}
を使用する場合のfind -exec cmd {} \;
と同様です。
ただし、Linuxのbashでテストされているため、機能しない場合は、フラグが異なる場合はgit-bash/cygwinのgrep --help
を確認することをお勧めします。通常は同じですが。
コマンドは、ディレクトリ(およびその他の非正規ファイル)を見つける可能性があります。ディレクトリは、sed
で編集できる通常のファイルではありません。
-type f
テストをfind
コマンドに追加すると、通常のファイルのみを処理できるようになります。
find . -type f -not -path \*.hg\* -exec sed -i 's/FCLP1025/FCLP1080/g' {} \;
または、標準のfind
オプションとより読みやすい引用符を使用して、
find . -type f ! -path '*.hg*' -exec sed -i 's/FCLP1025/FCLP1080/g' {} \;
.hg
ディレクトリを完全にスキップしたい場合は、-Prune
を使用してfind
の検索パスからそれらを削除します。
find . -name .hg -Prune -type f -exec sed -i 's/FCLP1025/FCLP1080/g' {} \;
これにより、find
は.hg
というディレクトリにさえ入りません。あなたのコマンドwouldそのようなディレクトリに入り、その中のすべてを-path
でテストしますが、これは少し非効率的です。
sed -i
(インプレース編集を行うfind
)は(診断メッセージがない限り)端末への出力を生成しないため、sed
コマンドの出力はないことに注意してください。 sed -i
の出力は、編集するファイルに入ります。
また、上記の最後のfind
コマンドは、everyファイルを編集しようとすることに注意してください。編集するファイルの名前がわかっている場合は、-name 'some pattern'
の直前に-exec
を追加して、sed
の実行をこれらのファイルのみに制限することをお勧めします。 。