web-dev-qa-db-ja.com

Sed編集できませんでした:通常のファイルではありません

私が直面しているこの問題を解決するために、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

ここで足りないものはありますか?

1
Laksh

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を確認することをお勧めします。通常は同じですが。

2
leondepeon

コマンドは、ディレクトリ(およびその他の非正規ファイル)を見つける可能性があります。ディレクトリは、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の実行をこれらのファイルのみに制限することをお勧めします。 。

0
Kusalananda