Gibt es eine Möglichkeit, sed dazu zu bringen, mich vor jedem Austausch um Bestätigung zu bitten? Ähnliches wie "c" bei Verwendung von "replace inside vim".
Macht sed das überhaupt?
Gibt es eine Möglichkeit, sed dazu zu bringen, mich vor jedem Austausch um Bestätigung zu bitten? Ähnliches wie "c" bei Verwendung von "replace inside vim".
Macht sed das überhaupt?
Antworten:
Dies sed
wäre wahrscheinlich nicht möglich, da es sich um einen nicht interaktiven Stream-Editor handelt. Das Einschließen sed
eines Skripts würde viel zu viel Nachdenken erfordern. Es ist einfacher, es einfach mit vim
:
vim -c '%s/PATTERN/REPLACEMENT/gc' -c 'wq' file.in
Da dies in den Kommentaren weiter unten erwähnt wurde, wird dies für mehrere Dateien verwendet, die mit einem bestimmten Dateinamen-Globbing-Muster im aktuellen Verzeichnis übereinstimmen:
for fname in file*.txt; do
vim -c '%s/PATTERN/REPLACEMENT/gc' -c 'wq' "$fname"
done
Oder, wenn Sie zuerst sicherstellen möchten, dass die Datei wirklich eine Linie enthält, die zuerst mit dem angegebenen Muster übereinstimmt, bevor Sie die Ersetzung durchführen,
for fname in file*.txt; do
grep -q 'PATTERN' "$fname" &&
vim -c '%s/PATTERN/REPLACEMENT/gc' -c 'wq' "$fname"
done
Die beiden obigen Shell-Schleifen wurden in find
Befehle umgewandelt, die dieselben Aktionen ausführen, jedoch für alle Dateien mit einem bestimmten Namen, die sich irgendwo in oder unter einem top-dir
Verzeichnis befinden.
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' {} \;
Oder verwenden Sie die ursprünglichen Shell-Schleifen und geben Sie find
Pfadnamen ein:
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 {} +
Sie, in jedem Fall nicht wollen , etwas zu tun wie for filename in $( grep -rl ... )
seit
grep
Ausführung beendet wird, bevor die erste Iteration der Schleife gestartet wird , die nicht relevant istgrep
würden in Wörter mit Leerzeichen aufgeteilt, und diese Wörter würden einer Dateinamenverschiebung unterzogen (dies disqualifiziert Pfadnamen, die Leerzeichen und Sonderzeichen enthalten).Verbunden:
sed
dass mehrere Dateien bearbeitet werden können, z. B. sed -i 's/old/new/g' /path/to/*.txt
oder ähnliches.
for i in $(grep -rl "old"); do vim -c "%s/old/new/gc" -c "wq" "$i"; done
Sie erhalten dies, indem Sie Folgendes tun:
:%s/OLD_TEXT/NEW_TEXT/gc
Insbesondere das Hinzufügen c
nach dem dritten Trennzeichen.
Beachten Sie, dass die Option 'c' nur in Vim funktioniert. Sie können es nicht über sed
die Befehlszeile verwenden.
sed
.
vim
, sodass diese Antwort zutreffend ist. Es ist jedoch klar, dass Vim und Sed unterschiedliche Fähigkeiten haben
Sie können sed
die Datei bearbeiten und das Ergebnis in einer temporären Datei speichern, die Sie dann interaktiv in die Originaldatei einfügen können sdiff
(siehe 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
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
}
Wenn Sie dies mit einem einzigen Argument eingeben - searchandreplace "AAA"
- sucht es nur im aktuellen Verzeichnis nach dieser Zeichenfolge, aber wenn Sie es mit doppelten Argumenten eingeben - searchandreplace AAA BBB
- werden Sie zusätzlich dazu aufgefordert, die erste durch die zweite "Zeile durch" zu ersetzen line "für jede Zeile.