Argumentos negativos a cabeza / cola

14

Las variantes de esta pregunta ciertamente se han hecho varias veces en diferentes lugares, pero estoy tratando de eliminar las últimas Mlíneas de un archivo sin suerte.

La segunda respuesta más votada en esta pregunta recomienda hacer lo siguiente para eliminar la última línea de un archivo:

head -n -1 foo.txt > temp.txt

Sin embargo, cuando intento eso en OSX y Zsh, obtengo:

head: illegal line count -- -1

¿Porqué es eso? ¿Cómo puedo eliminar las M últimas líneas y las primeras N líneas de un archivo dado?

Amelio Vazquez-Reina
fuente
1
¿Cuál es la salida de head --version? ¿Qué sistema estás usando?
jofel
@jofel head --versiondevuelve un error en realidad.
Amelio Vazquez-Reina

Respuestas:

20

Puede eliminar las primeras 12 líneas con:

tail -n +13

(Eso significa imprimir desde la línea 13).

Algunas implementaciones de soporte headsimilar a GNU head:

head -n -12

Pero eso no es estándar.

tail -r file | tail -n +12 | tail -r

funcionaría en aquellos sistemas que tienen tail -r(ver también GNU tac) pero son subóptimos.

Donde nes 1:

sed '$d' file

También puedes hacer:

sed '$d' file | sed '$d'

eliminar 2 líneas, pero eso no es óptimo.

Tu puedes hacer:

sed -ne :1  -e 'N;1,12b1' -e 'P;D'

Pero tenga en cuenta que no funcionará con grandes valores de n con algunas sedimplementaciones.

Con awk:

awk -v n=12 'NR>n{print line[NR%n]};{line[NR%n]=$0}'

Para eliminar mlíneas del principio y ndel final:

awk -v m=6 -v n=12 'NR<=m{next};NR>n+m{print line[NR%n]};{line[NR%n]=$0}'
Stéphane Chazelas
fuente
sed 'x;1d;$d'también podría usarse para obtener las dos últimas líneas. Y con un par de N's después 1dpodría usarse para obtener un poco más que eso, aunque en ese momento no ofrece ninguna ventaja sobre el N;P;Dciclo que ya recomienda.
mikeserv
Gracias. El último comando es extremadamente útil. Una pequeña advertencia de verano: no funciona cuando mo nson 0. De lo contrario, sería perfecto.
Amelio Vazquez-Reina
2

Puede usar la siguiente forma para eliminar las primeras N líneas y las últimas M líneas.

Con N=5, M=7y el archivo test.txt:

sed -n -e "6,$(($(wc -l < test.txt) - 7))p" test.txt

El comando imprime todas las líneas desde N + 1 hasta LastLine-M.

Otra opción es usar python:

python -c 'import sys;print "".join(sys.stdin.readlines()[5:-7]),' < test.txt
jofel
fuente
1

Puede eliminar las últimas Mlíneas (aquí M = 100) de un archivo con:

head -$(($(wc -l < foo.txt) - 100)) foo.txt > temp.txt
hacer
fuente