Eliminar líneas en un archivo de texto que contengan una cadena específica


¿Cómo usaría sed para eliminar todas las líneas de un archivo de texto que contengan una cadena específica?

Author: codeforester, 2011-03-23

14 answers

Para eliminar la línea e imprimir la salida a salida estándar:

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

Para modificar directamente el archivo:

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

Para modificar directamente el archivo (y crear una copia de seguridad):

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

Para los usuarios de Mac OS X y FreeBSD:

sed -i '' '/pattern/d' ./infile
 2075
Author: SiegeX,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-07 12:22:11

Hay muchas otras formas de eliminar líneas con una cadena específica además 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 y posterior)

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

GNU grep

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

Y por supuesto sed (imprimir la inversa es más rápido que la eliminación real):

sed -n '/pattern/!p' file
 543
Author: kurumi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-15 22:06:06

Puede usar sed para reemplazar las líneas en su lugar en un archivo. Sin embargo, parece ser mucho más lento que usar grep para el inverso en un segundo archivo y luego mover el segundo archivo sobre el original.

Por ejemplo

sed -i '/pattern/d' filename      

O

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

El primer comando tarda 3 veces más en mi máquina de todos modos.

 192
Author: slashdottir,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-19 15:07:10

La manera fácil de hacerlo, con GNU sed:

sed --in-place '/some string here/d' yourfile
 54
Author: Kevin Nguyen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-11 23:50:54

Usted puede considerar el uso ex (que es un editor estándar basado en comandos Unix):

ex +g/match/d -cwq file

Donde:

  • + ejecuta el comando Ex dado (man ex), igual que -c que ejecuta wq (write and quit)
  • g/match/d - Ex comando para eliminar líneas con match dado, ver: Potencia de g

El ejemplo anterior es un método compatible con POSIX para editar in situ un archivo según este post en Unix.SE y Especificaciones POSIX para ex.


La diferencia con sed es que:

sed es un Stream EDitor, no un editor de archivos.BashFAQ

A menos que disfrute de código indescifrable, sobrecarga de E/S y algunos otros efectos secundarios negativos. Así que básicamente algunos parámetros (como in-place / -i) son extensiones de FreeBSD no estándar y pueden no estar disponibles en otros sistemas operativos.

 26
Author: kenorb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-15 22:08:57

Estaba luchando con esto en Mac. Además, necesitaba hacerlo usando reemplazo variable.

Así que usé:

sed -i '' "/$pattern/d" $file

Donde $file es el archivo donde se necesita la eliminación y $pattern es el patrón que se emparejará para la eliminación.

Elegí el '' de este comentario .

Lo que hay que tener en cuenta aquí es el uso de comillas dobles en "/$pattern/d". Variable no funciona cuando usamos comillas simples.

 13
Author: Aniket Sinha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-15 22:15:45

Para obtener un resultado similar a inplace con grep puede hacer esto:

echo "$(grep -v "pattern" filename)" >filename
 12
Author: Jahid,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-06-13 19:24:59

He hecho una pequeña referencia con un archivo que contiene aproximadamente 345 000 líneas. El camino con grep parece ser alrededor de 15 veces más rápido que el método sed en este caso.

He intentado tanto con como sin la configuración LC_ALL=C, no parece cambiar los tiempos significativamente. La cadena de búsqueda (CDGA_00004.pdbqt.gz.tar) está en algún lugar en el medio del archivo.

Aquí están los comandos y los tiempos:

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
 10
Author: Jadzia,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-19 12:45:18
 8
Author: Oleg Mazko,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-20 13:28:37

También puedes usar esto:

 grep -v 'pattern' filename

Aquí -v imprimirá solo que no sea su patrón (eso significa invertir coincidencia).

 7
Author: Bhuvanesh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-15 22:07:13

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

 2
Author: Shizzmo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-16 23:51:31
perl -i    -nle'/regexp/||print' file1 file2 file3
perl -i.bk -nle'/regexp/||print' file1 file2 file3

El primer comando edita el archivo(s) inplace (-i).

El segundo comando hace lo mismo, pero mantiene una copia o copia de seguridad de los archivos originales mediante la adición .bk a los nombres de archivo (.bk se puede cambiar a cualquier cosa).

 2
Author: Kjetil S.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-08 12:07:39
cat filename | grep -v "pattern" > filename.1
mv filename.1 filename
 0
Author: Andrey Izman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-29 16:45:24

En caso de que alguien quiera hacerlo para coincidencias exactas de cadenas, puede usar la bandera -w en grep - w para whole. Es decir, por ejemplo, si desea eliminar las líneas que tienen el número 11, pero mantener las líneas con el número 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

También funciona con la bandera -f si desea excluir varios patrones exactos a la vez. Si" lista negra "es un archivo con varios patrones en cada línea que desea eliminar de"archivo":

grep -w -v -f blacklist file
 0
Author: FatihSarigol,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-15 22:18:52