In einer Datei mit vielen Zeilen möchte ich Zeilen löschen, die mit beginnen HERE IT IS.
Wie kann ich das nur mit Befehlszeilentools tun?
In einer Datei mit vielen Zeilen möchte ich Zeilen löschen, die mit beginnen HERE IT IS.
Wie kann ich das nur mit Befehlszeilentools tun?
Antworten:
Versuchen sed :
sed -i '/^HERE IT IS/d' <file>
WARNUNG: Es ist besser, eine Sicherungskopie zu erstellen, wenn Sie -iswitch of verwendensed :
sed -i.bak '/^HERE IT IS/d' <file>
Die Originaldatei bleibt unverändert, <file>.bakund die geänderte Datei bleibt unverändert <file>.
sed -i 's/^HERE IT IS/HERE IT IS\n/' <file>
sed '/^HERE IT IS/G' file.
Neben der sehr guten grepund sedAntworten , die Sie erhalten haben, sind hier einige andere Tools , die das gleiche tun können:
Einige Perl-Möglichkeiten:
perl -ne '/^HERE IT IS/ || print' file > newfile
perl -ne 'print if !/^HERE IT IS/' file > newfile
perl -ne 'print unless /^HERE IT IS/' file > newfile
Sie können den -iSchalter zu jedem Beispiel hinzufügen , um die Datei direkt zu bearbeiten:
perl -i.bak -ne '/^HERE IT IS/ || print' file
(gaffen
awk '!/^HERE IT IS/' file > newfile
Neuere Versionen (4.1.1 und höher) von GNU awk(der Standard awkunter Linux) können die Datei auch direkt bearbeiten:
gawk -i inplace '!/^HERE IT IS/' file
Shell ( bash, zsh, ksh, wahrscheinlich noch andere). Dies ist eine Art albern aber es können aber auch andere Werkzeuge sind besser gemacht werden.
while IFS= read -r line; do
[[ $line =~ ^"HERE IT IS" ]] || printf "%s\n" "$line"
done < file > newfile
basheine hat mich zum LOL gemacht)
printf "%s\n" "$line": Zitieren von $ line, um Leerzeichen zu erhalten, und Vermeiden von Echoproblemen (Interpretieren von Sonderzeichen usw.). und vermeidet die Notwendigkeit, auch hinzuzufügen --.
IFS=und -r, kann ich genauso gut den ganzen Weg gehen und es robust machen.
sed ist definitiv der richtige Weg.
Durch diese geringfügige Änderung des Befehls @heemayl wird die Zeile gelöscht, unabhängig davon, ob im Muster die gleiche Groß- / Kleinschreibung verwendet wird oder nicht.
sed -i '/HERE IT IS/Id' <file>
Wenn Sie mehrere Dateien in einem Verzeichnis haben, in dem Sie dies tun möchten, können Sie es mit find like so kombinieren.
find . -maxdepth 1 -type f -exec sed -i.bak '/HERE IT IS/Id' {} +
Die Option maxdepth bedeutet, dass dies nicht in Verzeichnisse wiederkehrt.
Eine weitere Python-Option:
#!/usr/bin/env python3
[print(l, end = "") for l in open(f).readlines() if not l.startswith("HERE IT IS")]
Wobei f der Pfad zur Datei zwischen Anführungszeichen ist.
Grep
grep -P '^(?!HERE IT IS)' file
(?!HERE IT IS)Negative Lookahead-Behauptung, die bewirkt, dass die Regex-Engine nur dann mit der gesamten Zeilenstartgrenze übereinstimmt^ ( die normalerweise von übereinstimmt ), wenn die Zeichenfolge nicht folgtHERE IT IS
Python
#!/usr/bin/python3
import sys
fil = sys.argv[1]
with open(fil) as f:
for line in f:
if not line.startswith('HERE IT IS'):
print(line, end="")
Speichern Sie das Skript beispielsweise in einer Datei script.pyund führen Sie es dann über den folgenden Befehl auf dem Terminal aus.
python3 script.py infile
[print(l, end = "") for l in open(fil).readlines() if not re.match("HERE IT IS", l)], aber es ist nicht viel effizienter als startswith. Ich habe mich gefragt, wie [print(l, end = "") for l in open(f).readlines() if not l.startswith("HERE IT IS")]ich die Ausgabe in einer Liste nicht erzeugen kann.
Sie können Vim im Ex-Modus verwenden:
ex -sc 'g/^HERE IT IS/d' -cx file
g globale Suche
d löschen
x speichern und schließen
vimwievim '+g/^HERE IT IS/d' +wq test.txt