W pliku z dużą ilością linii chcę usunąć linie zaczynające się od HERE IT IS
.
Jak mogę to zrobić przy użyciu tylko narzędzi wiersza polecenia?
W pliku z dużą ilością linii chcę usunąć linie zaczynające się od HERE IT IS
.
Jak mogę to zrobić przy użyciu tylko narzędzi wiersza polecenia?
Odpowiedzi:
Spróbuj sed
:
sed -i '/^HERE IT IS/d' <file>
OSTRZEŻENIE: Lepiej zrobić kopię zapasową, używając -i
przełącznika sed
:
sed -i.bak '/^HERE IT IS/d' <file>
Oryginalny plik pozostanie taki, jak <file>.bak
zmodyfikowany plik <file>
.
sed -i 's/^HERE IT IS/HERE IT IS\n/' <file>
sed '/^HERE IT IS/G' file
.
Oprócz bardzo dobrych grep
i otrzymanych sed
odpowiedzi, oto kilka innych narzędzi, które mogą zrobić to samo:
Kilka sposobów Perla:
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
Możesz dodać -i
przełącznik do dowolnego z przykładów, aby edytować plik w miejscu:
perl -i.bak -ne '/^HERE IT IS/ || print' file
(gapić się
awk '!/^HERE IT IS/' file > newfile
Nowsze wersje (4.1.1 i nowsze) GNU awk
(domyślnie awk
w Linuksie) mogą również edytować plik w miejscu:
gawk -i inplace '!/^HERE IT IS/' file
Shell ( bash
, zsh
, ksh
, prawdopodobnie inne). Jest to trochę głupie, można to zrobić, ale inne narzędzia są lepsze.
while IFS= read -r line; do
[[ $line =~ ^"HERE IT IS" ]] || printf "%s\n" "$line"
done < file > newfile
bash
sprawiła, że mnie LOL)
printf "%s\n" "$line"
: cytując $ line, aby zachować białe spacje i uniknąć niektórych problemów z echami (interpretacja specjalnych znaków itp.). i unika potrzeby dodawania --
.
IFS=
i -r
równie dobrze mogę zrobić wszystko, aby był solidny.
sed
to zdecydowanie najlepsza droga.
Ta niewielka modyfikacja polecenia @ heemayl spowodowała usunięcie linii bez względu na to, czy we wzorcu użyto tego samego przypadku, czy nie, ze względu na I w odwołaniu do wzorca.
sed -i '/HERE IT IS/Id' <file>
Jeśli masz kilka plików w katalogu, w którym chcesz to zrobić, możesz połączyć to z find w ten sposób.
find . -maxdepth 1 -type f -exec sed -i.bak '/HERE IT IS/Id' {} +
Opcja maxdepth oznacza, że nie będzie się to powtarzać w katalogach.
Inna opcja Pythona:
#!/usr/bin/env python3
[print(l, end = "") for l in open(f).readlines() if not l.startswith("HERE IT IS")]
Gdzie f jest ścieżką do pliku między cudzysłowami.
Grep
grep -P '^(?!HERE IT IS)' file
(?!HERE IT IS)
negatywne stwierdzenie wyprzedzające, które powoduje, że silnik wyrażenia regularnego dopasowuje całą granicę początkową linii ( która zwykle jest dopasowywana^
) tylko wtedy, gdy nie następuje po niej ciągHERE IT IS
pyton
#!/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="")
Zapisz skrypt w pliku, powiedz, script.py
a następnie uruchom go za pomocą poniższego polecenia na terminalu.
python3 script.py infile
[print(l, end = "") for l in open(fil).readlines() if not re.match("HERE IT IS", l)]
, ale nie jest to o wiele bardziej wydajne niż startswith
. Zastanawiałem się, jak [print(l, end = "") for l in open(f).readlines() if not l.startswith("HERE IT IS")]
nie będzie generować wyników na liście.
Możesz używać Vima w trybie Ex:
ex -sc 'g/^HERE IT IS/d' -cx file
g
globalne wyszukiwanie
d
usunąć
x
Zapisz i zamknij
vim
takiegovim '+g/^HERE IT IS/d' +wq test.txt