unix - utilizando - ¿Eliminar los números de línea específicos de un archivo de texto usando sed?
sed linux eliminar linea (6)
Esto es a menudo un síntoma de un antipatrón. La herramienta que produjo los números de línea puede ser reemplazada por una que borre las líneas de inmediato. Por ejemplo;
grep -nh error logfile | cut -d: -f1 | deletelines logfile
(donde deletelines
es la utilidad que imaginas que necesitas) es lo mismo que
grep -v error logfile
Una vez dicho esto, si se encuentra en una situación en la que realmente necesita realizar esta tarea, puede generar un script sed
simple a partir del archivo de números de línea. Con humor (pero tal vez un poco confuso) puedes hacer esto con sed
.
sed ''s%$%d%'' linenumbers
Esto acepta un archivo de números de línea, uno por línea, y produce, en salida estándar, los mismos números de línea con d
anexados después de cada uno. Este es un script sed
válido, que podemos guardar en un archivo, o (en algunas plataformas) canalizar a otra instancia sed
:
sed ''s%$%d%'' linenumbers | sed -f - logfile
En algunas plataformas, sed -f
no entiende el argumento de opción -
para significar entrada estándar, por lo que debe redirigir la secuencia de comandos 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 de la opción -f
para que sed
edite el archivo de destino en su lugar, en lugar de producir el resultado en la salida estándar. En las plataformas * BSDish (incluido OSX), debe proporcionar un argumento explícito a -i
también; un modismo común es proporcionar un argumento vacío; -i ''''
.
Quiero eliminar uno o más números de línea específicos de un archivo. ¿Cómo haría esto usando sed?
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 para el 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 O y AND . -
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 |
+-----+------+----------+------------+
Puede eliminar una única línea en particular con su número de línea mediante el archivo sed -i ''33d''
Esto eliminará la línea en el número de 33 líneas y guardará el archivo actualizado.
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 en file.bak
y eliminará las líneas dadas.
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
$