各代替の前にsedに確認を依頼してもよろしいですか?

各代替の前にsedに確認を依頼してもよろしいですか?

各代替の前に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 ... )ことをしたい

  1. grepこれはループの最初の反復を開始する前に完了する必要があります。つまり、優雅ではない
  2. 返されたパス名は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」に置き換える必要があります。最初の行"を各行に割り当てます。

関連情報