私のコマンドは次のとおりです(意図的に中断されました)。
grep FOO "/Users/gjtorikian/blah" -l | xargs sed -i '' '/FOO/{s/FOO/BAR/g; w /dev/stdout
}'
高レベルで:ディレクトリgrep
のFOO。インライン置換()を実行し、ファイルblah
名のみを-l
パイプします。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
。grep
しばらくしてくださいsed
。
答え1
grep
1つの可能性はの出力を渡すことです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
答え2
私の母国語は英語ではないので理解できないかもしれません。
ディレクトリを「grep」するには、「-r」が必要です。ファイル名のみを印刷し、最初の発生後にgrepを停止するには、「-l」を使用します。
# 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
答え3
現在のディレクトリでFOOをBARに繰り返し交換します(自動モード)。
grep -rl 'FOO' | xargs sed -i 's/FOO/BAR/'
答え4
短い冗談
grep -n FOO * -R|awk -F\: '{ print $1 }'|sort|uniq|while read file; do sed -i 's/FOO/BAR/g' $file; done