
各代替の前にsedに私に確認を依頼する方法はありますか? vimで置換を使用するときは「c」に似ています。
sedは本当にこのようなことをしますか?
答え1
sed
非対話型フローエディタであるため、使用できない場合があります。これをsed
スクリプトにカプセル化するには、あまりにも多くの考えが必要です。これを行う方が簡単ですvim
。
vim -c '%s/PATTERN/REPLACEMENT/gc' -c 'wq' file.in
以下の説明で説明されているので、特定のファイル名ワイルドカードパターンと一致する現在のディレクトリ内の複数のファイルにこれを使用する方法は次のとおりです。
for fname in file*.txt; do
vim -c '%s/PATTERN/REPLACEMENT/gc' -c 'wq' "$fname"
done
または、置換を実行する前に、ファイルに指定されたパターンに一致する行が実際に含まれていることを確認するには、次の手順を実行します。
for fname in file*.txt; do
grep -q 'PATTERN' "$fname" &&
vim -c '%s/PATTERN/REPLACEMENT/gc' -c 'wq' "$fname"
done
上記の2つのシェルループは同じ操作を実行するコマンドを持つように変更されましたが、特定のfind
ディレクトリ内またはその下にtop-dir
特定の名前を持つすべてのファイルについて
find top-dir -type f -name 'file*.txt' \
-exec vim -c '%s/PATTERN/REPLACEMENT/gc' -c 'wq' {} \;
find top-dir -type f -name 'file*.txt' \
-exec grep -q 'PATTERN' {} \; \
-exec vim -c '%s/PATTERN/REPLACEMENT/gc' -c 'wq' {} \;
または、raw シェルループを使用し、find
ここにパス名を追加します。
find top-dir -type f -name 'file*.txt' -exec sh -c '
for pathname do
vim -c "%s/PATTERN/REPLACEMENT/gc" -c "wq" "$pathname"
done' sh {} +
find top-dir -type f -name 'file*.txt' -exec sh -c '
for pathname do
grep -q "PATTERN" "$pathname" &&
vim -c "%s/PATTERN/REPLACEMENT/gc" -c "wq" "$pathname"
done' sh {} +
とにかくあなたはそうですいいえ似たようなfor filename in $( grep -rl ... )
ことをしたい
grep
これはループの最初の反復を開始する前に完了する必要があります。つまり、優雅ではないと- 返されたパス名は
grep
空白の単語に分割され、これらの単語はファイル名のグロービング(スペースと特殊文字を含むパス名を抑制する)を経ます。
関連:
答え2
次のようにしてこれを達成できます。
:%s/OLD_TEXT/NEW_TEXT/gc
c
具体的には、3番目の区切り記号の後に追加してください。
sed
'c'オプションはVimでのみ機能し、コマンドラインでは使用できません。
答え3
sed
ファイルにアクションを実行し、結果を一時ファイルに保存し、対話形式で元のファイルにパッチを適用するために使用できます(sdiff
参照:http://www.gnu.org/software/diffutils/manual/diffutils.html#Invoking-sdiff):
sed -r 's/something/something_else/g' my_file > tmp_file
sdiff -o my_file -s -d my_file tmp_file
答え4
searchandreplace () {
if [ -z $2 ] ; then
realpath * | xargs grep -ins --directories=skip --color=always "$1" | nl -s "."
else
realpath * | xargs grep -ins --directories=skip --color=always "$1" | nl -s "."
exp=$(realpath * | xargs grep -ins --directories=skip --color=never "$1" | cut -d':' -f1,2 | awk -F':' '{print $2 $1}' | sed -E "s|^[0-9]+|sed -i \'&s/|; s|//|/"$1"/"$2"/g\' /|")
IFS=$'\n'
for d in $exp
do
read -p "Exec $(echo -e -n "\033[1;31m$d\033[0m")? " -e REP
if [ "$REP" = y ]; then
echo `bash -c $d`;
fi
done
fi
}
単一の引数を指定する場合は、searchandreplace "AAA"
その文字列の現在のディレクトリのみを検索しますが、二重引数を指定するsearchandreplace AAA BBB
場合は、上記以外に2番目の「line by」に置き換える必要があります。最初の行"を各行に割り当てます。