これが私のコマンドです(意図的に中断します):

grep FOO "/Users/gjtorikian/blah" -l | xargs sed -i "" "/FOO/{s/FOO/BAR/g; w /dev/stdout }" 

高-レベル:blahディレクトリのFOOのgrep;ファイル名だけをパイプします(-l)to sed; sedはインライン置換(-i "")を実行し、出力します変更された用語のみ/dev/stdoutに変更しました。

-lを省略した場合パイプで、これをgrepから取得します:

/Users/gjtorikian/blah/baz.cs:1:FOO /Users/gjtorikian/blah/bar.js:1:FOO 

必要なのはsedインライン置換を実行してから、置換されたファイルと用語を表示します。例:

/Users/gjtorikian/blah/baz.cs:1:BAR /Users/gjtorikian/blah/bar.js:1:BAR 

そのようなことは可能ですか?重要な場合は、grep / sedのみで保持したいと思います。2回目のivid = “を実行する必要がありますか。 85af “>

コメント

  • 'への道がわからないsedで現在のファイル名を取得するため、おそらく2番目のgrepが必要になります。
  • また、'は、その'がデフォルトです。
  • OS Xでは、''はデフォルトではありません。 。

回答

1つの可能性は、grepを別のsedフィルターに。

 grep -l FOO "/Users/gjtorikian/blah/"* | { tee /dev/fd/3 | xargs sed -i -e "/FOO/{" -e "s/FOO/BAR/g" -e "w /dev/stdout" } 3>&1 | sed "s/:FOO$/:BAR/"  

一致するものが見つかったら、sedに行番号を出力させ(=コマンドを使用)、さらに実行することができます。後処理。

awkを使用する方がおそらく明確です。

 for x in "/Users/gjtorikian/blah/"*; do awk " sub(/FOO/, "BAR") {found=1; print FILENAME ":" NR ":" "BAR" >"/dev/stderr"} 1 {print} END {exit(!found)} " "$x" >"$x.tmp" && mv "$x.tmp" "$x" done  

回答

As I “mn英語を母国語とする人は、おそらく「理解できませんでした。」

ディレクトリを「grep」するには、「-r」が必要です。 「-l」を使用すると、ファイル名だけが出力され、最初に発生した後はgrepが停止します。

# pattern=/home ; grep -l "$pattern" /etc/[a-z]* 2>/dev/null | while read line ; do echo "$line:$pattern" ; done /etc/adduser.conf:/home /etc/fstab:/home /etc/fstab~:/home /etc/libuser.conf:/home /etc/mpd.conf:/home /etc/mpd.conf~:/home /etc/mtab:/home /etc/netscsid.conf:/home /etc/passwd:/home /etc/passwd-:/home /etc/sudoers:/home /etc/sudoers.tmp~:/home 

回答

あなたは”一度にやろうとすると問題が複雑になりすぎると思います。

grep -H -n /Users/gjtorikian/blah | sed "s/\(^.*?:[0-9]+?:\).*FOO.*/\1BAZ/" 

を実行するだけです。行番号と置換を含むファイルのリストを取得します(ファイル名にコロンが含まれていない限り、これは機能するはずですが、Mac OSでは「とにかく悪い考えです…)」後で発行できます

sed -i "" "s/FOO/BAR/g" /Users/gjtorikian/blah 

ここではgrepとxargは必要ありません(ファイルがたくさんある場合は「find … | xarg」を実行できます)。重複については、2行をスクリプトまたは関数に入れて、そこで変数の置換を行うことができます。

コメント

  • sed -i ...は、ストリームが変更されていない場合でもファイル時間を変更します。
  • @jww:'そうです、その' sなぜなら、はファイルエディターではなくストリームエディターであるため、-iオプションはUNIX哲学( mywiki.wooledge)に違反しています。 .org / BashFAQ / 021#Using_nonstandard_tools )。これを回避したい場合は、exex -sc '%s/FOO/BAR/ge|x' /Users/gjtorikian/blahなど)を使用してください。

回答

現在のディレクトリでFOOをBARに再帰的に置き換えます(クワイエットモード)

grep -rl "FOO" | xargs sed -i "s/FOO/BAR/" 

回答

1つのライナー

grep -n FOO * -R|awk -F\: "{ print $1 }"|sort|uniq|while read file; do sed -i "s/FOO/BAR/g" $file; done 

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です