una script que para manejo lineas linea eliminar ejemplo contengan con comando caracter cadenas borrar archivo shell sed text-parsing in-place

shell - script - Eliminar líneas en un archivo de texto que contienen una cadena específica



sed eliminar caracter (14)

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


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


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 posteriores)

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 el inverso es más rápido que la eliminación real):

sed -n ''/pattern/!p'' file


He hecho un pequeño punto de referencia con un archivo que contiene aproximadamente 345 000 líneas. La forma con grep parece ser alrededor de 15 veces más rápida que el método sed en este caso.

He intentado con y sin el ajuste 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 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


La forma más fácil de hacerlo, con GNU sed :

sed --in-place ''/some string here/d'' yourfile


Para eliminar la línea e imprimir la salida a la 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 usuarios de Mac OS X y FreeBSD:

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


Para obtener un resultado in situ con grep puede hacer esto:

echo "$(grep -v "pattern" filename)" >filename


Puede considerar usar ex (que es un editor estándar basado en comandos de Unix):

ex +g/match/d -cwq file

dónde:

  • + ejecuta el comando Ex dado ( man ex ), igual que -c que ejecuta wq (escribir y salir)
  • g/match/d - Ex comando para eliminar líneas con una match dada, ver: Potencia de g

El ejemplo anterior es un método compatible con POSIX para la edición en contexto de un archivo según esta publicación en Unix.SE y POSIX especificaciones para ex .

La diferencia con sed es que:

sed es un editor de S tream ED , no un editor de archivos. BashFAQ

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


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.

p.ej

sed -i ''/pattern/d'' filename

o

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

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



También puedes usar esto:

grep -v ''pattern'' filename

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


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

Así que utilicé:

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

donde $file es el archivo donde se necesita la eliminación y $pattern es el patrón que debe coincidir para su eliminación.

Escogí el '''' de este comment .

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


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


cat filename | grep -v "pattern" > filename.1 mv filename.1 filename


perl -i -nle''/regexp/||print'' file1 file2 file3 perl -i.bk -nle''/regexp/||print'' file1 file2 file3

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

El segundo comando hace lo mismo pero mantiene una copia o copia de seguridad de los archivos originales al agregar .bk a los nombres de los archivos (.bk puede cambiarse a cualquier cosa).