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 -i
switch of verwendensed
:
sed -i.bak '/^HERE IT IS/d' <file>
Die Originaldatei bleibt unverändert, <file>.bak
und 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 grep
und sed
Antworten , 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 -i
Schalter 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 awk
unter 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
bash
eine 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.py
und 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
vim
wievim '+g/^HERE IT IS/d' +wq test.txt