Pregunta

Quiero eliminar uno o más números de línea específicos de un archivo.¿Cómo haría esto usando sed?

¿Fue útil?

Solución

Si quiere borrar las líneas 5 a 10 y de 12:

sed -e '5,10d;12d' file

Esto imprimirá los resultados en la pantalla. Si desea guardar los resultados en el mismo archivo:

sed -i.bak -e '5,10d;12d' file

Esto copia el archivo hasta file.bak y eliminar las líneas dadas.

Nota:. Los números de línea comienzan en 1. La primera línea del archivo es 1, no 0

Otros consejos

Puede eliminar una sola línea particular con su número de línea por    sed -i '33d' archivo

Esto eliminará la línea en 33 el número de línea y guardar el archivo actualizado.

y awk así

awk 'NR!~/^(5|10|25)$/' file
$ cat foo
1
2
3
4
5
$ sed -e '2d;4d' foo
1
3
5
$ 

Esto es muy a menudo un síntoma de un anti patrón. La herramienta que produjo los números de línea bien puede ser reemplazado con uno que elimina las líneas de inmediato. Por ejemplo;

grep -nh error logfile | cut -d: -f1 | deletelines logfile

(donde deletelines es la utilidad que se está imaginando que necesita) es el mismo que

grep -v error logfile

Una vez dicho esto, si se encuentra en una situación en la que realmente necesita para llevar a cabo esta tarea, se puede generar una secuencia de comandos sed sencilla desde el archivo de números de línea. Con humor (pero quizás un poco confusa) se puede hacer esto con sed.

sed 's%$%d%' linenumbers

Esta acepta un archivo de números de línea, una por línea, y produce, en la salida estándar, los mismos números de línea con d añaden después de cada. Este es un script válido sed, que podemos guardar en un archivo, o (en algunas plataformas) tubería a otra instancia sed:

sed 's%$%d%' linenumbers | sed -f - logfile

En algunas plataformas, sed -f no entender la - argumento de opción en el sentido de la entrada estándar, así que hay que redirigir la secuencia de comandos en un archivo temporal, y limpiarlo cuando haya terminado, o quizás reemplazar el tablero solitario con /dev/stdin o /proc/$pid/fd/1 si su sistema operativo (o cáscara) tiene eso.

Como siempre, se puede añadir la opción -i antes -f tener sed editar el archivo de destino en su lugar, en vez de producir el resultado en la salida estándar. En las plataformas * BSDish (incluyendo OS X) es necesario proporcionar un argumento explícito para -i así; un lenguaje común es la de suministrar un argumento vacío; -i ''.

Me gustaría proponer una generalización con awk.

Cuando el archivo se realiza mediante bloques de un tamaño fijo y las líneas para eliminar se repiten para cada bloque, AWK puede funcionar bien de tal manera

awk '{nl=((NR-1)%2000)+1; if ( (nl<714) || ((nl>1025)&&(nl<1029)) ) print  $0}'
 OriginFile.dat > MyOutputCuttedFile.dat

En este ejemplo, el tamaño del bloque es 2000 y quiero imprimir las líneas [1..713] y [1026..1029].

  • NR es la variable utilizada por awk para almacenar el número de línea actual.
  • % da el resto (o módulo) de la división de dos números enteros;
  • nl=((NR-1)%BLOCKSIZE)+1 Aquí escribimos en la variable nl el número de línea dentro del bloque actual.(vea abajo)
  • || y && son el operador lógico O y Y.
  • print $0 escribe la línea completa

Why ((NR-1)%BLOCKSIZE)+1:
(NR-1) We need a shift of one because 1%3=1, 2%3=2, but 3%3=0.
  +1   We add again 1 because we want to restore the desired order.

+-----+------+----------+------------+
| NR  | NR%3 | (NR-1)%3 | (NR-1)%3+1 |
+-----+------+----------+------------+
|  1  |  1   |    0     |     1      |
|  2  |  2   |    1     |     2      |
|  3  |  0   |    2     |     3      |
|  4  |  1   |    0     |     1      |
+-----+------+----------+------------+

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top