これが私のコマンドです(意図的に中断します):
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行をスクリプトまたは関数に入れて、そこで変数の置換を行うことができます。
コメント
回答
現在のディレクトリで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
sed -i ...
は、ストリームが変更されていない場合でもファイル時間を変更します。-i
オプションはUNIX哲学( mywiki.wooledge)に違反しています。 .org / BashFAQ / 021#Using_nonstandard_tools )。これを回避したい場合は、ex
(ex -sc '%s/FOO/BAR/ge|x' /Users/gjtorikian/blah
など)を使用してください。