Quiero eliminar uno o más números de línea específicos de un archivo. ¿Cómo haría esto usando sed?
Quiero eliminar uno o más números de línea específicos de un archivo. ¿Cómo haría esto usando sed?
Respuestas:
Si desea eliminar las líneas 5 a 10 y 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 respaldará el archivo 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.
sed -e '5,$d' file
sed -e '5d' file
. La sintaxis es <address><command>
; donde <address>
puede ser una sola línea 5
o un rango de líneas 5,10
, y el comando d
elimina la línea o líneas dadas. Las direcciones también pueden ser expresiones regulares o el signo de dólar que $
indica la última línea del archivo.
Puede eliminar una sola línea particular con su número de línea por
sed -i '33d' file
Esto eliminará la línea en el número de línea 33 y guardará el archivo actualizado.
sed -i '0,/<TARGET>/{/<NEW_VALUE>/d;}' '<SOME_FILE_NAME>'
. ¡Gracias!
y awk también
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 antipatrón. La herramienta que produjo los números de línea bien puede reemplazarse por una que elimine las líneas de inmediato. Por ejemplo;
grep -nh error logfile | cut -d: -f1 | deletelines logfile
(¿dónde deletelines
está la utilidad que imagina que necesita?) es lo mismo que
grep -v error logfile
Dicho esto, si se encuentra en una situación en la que realmente necesita realizar esta tarea, puede generar un sed
script simple a partir del archivo de números de línea. Con humor (pero quizás un poco confuso) puedes hacer esto sed
.
sed 's%$%d%' linenumbers
Esto acepta un archivo de números de línea, uno por línea, y produce, en la salida estándar, los mismos números de línea d
añadidos después de cada uno. Este es un sed
script válido , que podemos guardar en un archivo, o (en algunas plataformas) canalizar a otra sed
instancia:
sed 's%$%d%' linenumbers | sed -f - logfile
En algunas plataformas, sed -f
no entiende el argumento de la opción -
que significa entrada estándar, por lo que debe redirigir el script a un archivo temporal y limpiarlo cuando haya terminado, o tal vez reemplazar el guión solitario con /dev/stdin
o /proc/$pid/fd/1
si su sistema operativo (o shell ) tiene eso.
Como siempre, puede agregar -i
antes la -f
opción de sed
editar el archivo de destino en lugar de producir el resultado en la salida estándar. En las plataformas * BSDish (incluido OSX) también debe proporcionar un argumento explícito -i
; un idioma común es proporcionar un argumento vacío; -i ''
.
p
lugar de d
, junto con la opción -n
(no funcionará sin -n
, y !d
tampoco funcionará).
Me gustaría proponer una generalización con awk.
Cuando el archivo está hecho por 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 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 OR y AND .print $0
escribe la línea completaWhy ((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 |
+-----+------+----------+------------+