Șterge linii într-un fișier text care conțin un anumit șir

Cum mi-ar folosi sed pentru a șterge toate liniile într-un fișier text care conțin un anumit șir de caractere?

Soluția

Pentru a elimina line și de imprimare de ieșire standard de ieșire:

sed '/pattern to match/d' ./infile

Pentru a modifica direct la fișier – nu funcționează cu BSD sed:

sed -i '/pattern to match/d' ./infile

Același lucru, dar pentru BSD sed (Mac OS X și FreeBSD) – nu funcționează cu GNU sed:

sed -i '' '/pattern to match/d' ./infile

Pentru a modifica direct fișierul (și de a crea o copie de rezervă) – funcționează cu BSD și GNU sed:

sed -i.bak '/pattern to match/d' ./infile
Comentarii (25)

Există multe alte moduri de a șterge linii cu specific șir în afară de sed:

AWK

awk '!/pattern/' file > temp && mv temp file

Ruby (1.9+)

ruby -i.bak -ne 'print if not /test/' file

Perl

perl -ni.bak -e "print unless /pattern/" file

Shell (bash 3.2 și mai târziu)

while read -r line
do
  [[ ! $line =~ pattern ]] && echo "$line"
done  o
mv o file

GNU grep

grep -v "pattern" file > temp && mv temp file

Și, desigur, sed (imprimare inversă este mai rapid decât ștergerea reală):

sed -n '/pattern/!p' file
Comentarii (7)

Puteți utiliza sed să înlocuiască linii în loc într-un fișier. Cu toate acestea, se pare a fi mult mai lent decât folosind grep pentru inversul într-un al doilea fișier și apoi se deplasează de-al doilea dosar în original.

de exemplu

sed -i '/pattern/d' filename      

sau

grep -v "pattern" filename > filename2; mv filename2 filename

Prima comandă are de 3 ori mai mult pe masina mea oricum.

Comentarii (9)

Cea mai ușoară cale de a face asta, cu GNU sed:

sed --in-place '/some string here/d' yourfile
Comentarii (4)

Puteți lua în considerare, folosind ex (care este un standard de comandă Unix-based editor):

ex +g/match/d -cwq file

în cazul în care:

  • + execută dat Ex de comandă (bărbat ex), la fel ca "- c " care executăwq` (scrie si renuntat)
  • g/meci/d - Ex de comandă pentru a șterge linii cu date de "meci", a se vedea: Putere de g

Exemplul de mai sus este un POSIX compatibile metodă în loc de editare a unui fișier ca pe acest post la Unix.SE și POSIX specificațiile pentru ex.


Diferența cu sed este asta:

sed e o Stream EDitor, nu un editor de fișier.BashFAQ

Dacă vă bucura de unportable cod, I/O de regie și alte efecte secundare rele. Deci, practic unii parametri (cum ar fi în-loc/i-i) sunt non-standard FreeBSD extensii și pot să nu fie disponibile pe alte sisteme de operare.

Comentarii (2)

Am fost lupta cu acest lucru pe Mac. În Plus, am nevoie sa o fac folosind variabila de înlocuire.

Așa că am folosit:

sed -am '' "/$model/d" $file

unde $de fișier este fișierul în care eliminarea este necesară și$model este modelul pentru a fi potrivite pentru ștergere.

Am ales'' din acest comentariu.

Lucru de reținut aici este utilizarea de ghilimele duble în"/$model/d"`. Variabila a câștigat't de lucru atunci când vom folosi ghilimele simple.

Comentarii (2)

Am facut un mic benchmark cu un fișier care conține aproximativ 345 000 de linii. La fel cu grep pare a fi în jurul valorii de 15 ori mai repede decât sed metodă în acest caz.

Am încercat atât cu, cât și fără stabilirea LC_ALL=C, nu pare a modifica timpii de semnificativ. Șirul de căutare (CDGA_00004.pdbqt.gz.tar) este undeva la mijloc de fișier.

Aici sunt comenzile și timpii:

time sed -i "/CDGA_00004.pdbqt.gz.tar/d" /tmp/input.txt

real    0m0.711s
user    0m0.179s
sys     0m0.530s

time perl -ni -e 'print unless /CDGA_00004.pdbqt.gz.tar/' /tmp/input.txt

real    0m0.105s
user    0m0.088s
sys     0m0.016s

time (grep -v CDGA_00004.pdbqt.gz.tar /tmp/input.txt > /tmp/input.tmp; mv /tmp/input.tmp /tmp/input.txt )

real    0m0.046s
user    0m0.014s
sys     0m0.019s
Comentarii (2)

Puteți folosi, de asemenea, acest lucru:

 grep -v 'pattern' filename

Aici -v va imprima numai, altele decât modelul (care înseamnă invertit meci).

Comentarii (0)

Pentru a obține un efectivă ca urmare cu grep puteți face acest lucru:

echo "$(grep -v "pattern" filename)" >filename
Comentarii (1)
perl -i    -nle'/regexp/||print' file1 file2 file3
perl -i.bk -nle'/regexp/||print' file1 file2 file3

Prima comanda editează fișierul(e) efectivă (-i).

Cea de-a doua comanda face acelasi lucru, dar păstrează o copie sau o copie de rezervă a fișierului original(e) prin adăugarea .bk la nume de fișiere (.bk poate fi schimbat pentru nimic).

Comentarii (0)

echo-e "/thing_to_delete\ndd\033:x\n" | vim file_to_edit.txt

Comentarii (0)
cat filename | grep -v "pattern" > filename.1
mv filename.1 filename
Comentarii (2)

Doar în cazul în care cineva vrea să-l facă pentru potriviri exacte de siruri de caractere, puteți utiliza -w pavilion în grep - w pentru tot. Asta este, de exemplu, dacă doriți să ștergeți liniile care au numărul 11, dar păstrează liniile cu număr de 111:

-bash-4.1$ head file
1
11
111

-bash-4.1$ grep -v "11" file
1

-bash-4.1$ grep -w -v "11" file
1
111

De asemenea, funcționează cu -f flag dacă doriți să excludeți mai multe exactă modele la o dată. Dacă "lista neagra" este un fișier cu mai multe modele pe fiecare linie pe care doriți să-l ștergeți din "fișier":

grep -w -v -f blacklist file
Comentarii (1)