Y si necesita usar tuberías por alguna razón, entonces así:
cat file.txt |(head; tail)
Nota: imprimirá líneas duplicadas si el número de líneas en file.txt es menor que las líneas predeterminadas de encabezado + líneas predeterminadas de cola.
Estrictamente hablando, esto no le da la cola del archivo original, pero la cola de la secuencia después de headhaber consumido las primeras 10 líneas del archivo. (Compare esto con head < file.txt; tail < file.txtun archivo con menos de 20 líneas). Solo un punto muy pequeño a tener en cuenta. (Pero aún así +1.)
chepner
15
Agradable. Si desea un espacio entre las partes de la cabeza y la cola: (cabeza; eco; cola) <file.txt
Simon Hibbs
3
Curioso sobre por qué / cómo funciona esto. Lo
formulé
9
@nametal En realidad, es posible que ni siquiera obtengas tanto. Si bien headsolo muestra las primeras 10 líneas de su entrada, no se garantiza que no haya consumido más para encontrar el final de la décima línea, dejando menos de la entrada para lessmostrar.
chepner
20
Lamento decirlo, pero la respuesta solo funciona en algunos casos. seq 100 | (head; tail)me da solo los primeros 10 números. Solo en un tamaño de entrada mucho más grande (como seq 2000) la cola recibe algo de entrada.
¿Qué pasa si el archivo tiene más o menos de 200 líneas? ¿Y no sabes el número de líneas ab initio?
Paul
@Paul me he cambiado sedaed
kev
14
Para una secuencia pura (por ejemplo, salida de un comando), puede usar 'tee' para bifurcar la secuencia y enviar una secuencia a la cabeza y otra a la cola. Esto requiere el uso de la función '> (lista)' de bash (+ / dev / fd / N):
( COMMAND | tee /dev/fd/3| head )3>>( tail )
o usando / dev / fd / N (o / dev / stderr) más subcapas con redireccionamiento complicado:
(( seq 1100| tee /dev/fd/2| head 1>&3)2>&1| tail )3>&1(( seq 1100| tee /dev/stderr | head 1>&3)2>&1| tail )3>&1
(Ninguno de estos funcionará en csh o tcsh).
Para algo con un poco de mejor control, puede usar este comando perl:
COMMAND | perl -e 'my $size = 10; my @buf = (); while (<>) { print if $. <= $size; push(@buf, $_); if ( @buf > $size ) { shift(@buf); } } print "------\n"; print @buf;'
+1 para soporte de transmisión. Puede reutilizar stderr:COMMAND | { tee >(head >&2) | tail; } |& other_commands
jfs
2
por cierto, se rompe para archivos de mayor tamaño que el tamaño del búfer (8K en mi sistema). cat >/dev/nulllo corrige:COMMAND | { tee >(head >&2; cat >/dev/null) | tail; } |& other_commands
jfs
Me encantó la solución, pero después de jugar durante un tiempo, noté que en algunos casos la cola corría antes que la cabeza ... no hay un orden garantizado entre heady tailcomandos: \ ...
Jan
7
(sed -u 10q; echo ...; tail)< file.txt
Solo otra variación del (head;tail)tema, pero evitando el problema inicial de llenado del búfer para archivos pequeños.
Agradable, siempre los he usado caty / heado tailentubado, ¡es bueno saber que puedo usarlos individualmente!
Paul
¿Cómo puedo canalizar estos primeros 10 + últimos 10 en otro comando?
toop
1
@Paul - con 'your_program' como wc -l devuelve 10 en lugar de 20
toop
3
o, sin tener que generar una subcapa: { head file; tail file; } | prog(espaciado dentro de las llaves, y el punto y coma final son obligatorios)
Glenn Jackman
1
Wow ... un voto negativo por tener una respuesta bastante similar a las demás (pero marcada con tiempo antes de ellos) después de casi dos años, de alguien que eligió no publicar por qué votaron negativamente. ¡Agradable!
El problema aquí es que los programas orientados a secuencias no conocen de antemano la longitud del archivo (porque puede que no haya uno, si es una secuencia real).
herramientas como tailalmacenar las últimas n líneas vistas y esperar el final de la transmisión, luego imprimir.
si desea hacer esto en un solo comando (y hacer que funcione con cualquier desplazamiento, y no repita líneas si se superponen) tendrá que emular este comportamiento que mencioné.
prueba este awk:
awk -v offset=10'{ if (NR <= offset) print; else { a[NR] = $0; delete a[NR-offset] } } END { for (i=NR-offset+1; i<=NR; i++) print a[i] }' yourfile
necesita más trabajo para evitar problemas cuando el desplazamiento es mayor que el archivo
Samus_
Yay, esto funciona con salida canalizada, no solo archivos: a.out | awk -v ...
Camille Goudeseune
de hecho :) pero ese es el comportamiento normal de awk, la mayoría de los programas de línea de comandos funcionan en stdin cuando se invocan sin argumentos.
Samus_
1
Muy cerca del comportamiento deseado, pero parece que para <10 líneas agrega líneas nuevas adicionales.
sorin
3
Me llevó mucho tiempo terminar con esta solución, que parece ser la única que cubrió todos los casos de uso (hasta ahora):
He estado buscando esta solución por un tiempo. Lo intenté yo mismo con sed, pero el problema de no saber de antemano la longitud del archivo / flujo era insuperable. De todas las opciones disponibles anteriormente, me gusta la solución awk de Camille Goudeseune. Él hizo una nota de que su solución dejaba líneas en blanco adicionales en la salida con un conjunto de datos suficientemente pequeño. Aquí proporciono una modificación de su solución que elimina las líneas adicionales.
headtail(){ awk -v offset="$1"'{ if (NR <= offset) print; else { a[NR] = $0; delete a[NR-offset] } } END { a_count=0; for (i in a) {a_count++}; for (i=NR-a_count+1; i<=NR; i++) print a[i] }';}
Bueno, siempre puedes encadenarlos juntos. Me gusta así
head fiename_foo && tail filename_foo. Si eso no es suficiente, puede escribir una función bash en su archivo .profile o en cualquier archivo de inicio de sesión que utilice:
head_and_tail(){
head $1 && tail $1
}
Y, más tarde invocarla desde el shell de comandos: head_and_tail filename_foo.
¿Por qué usar cat cuando solo puedes llamar a head -10 file.txt?
jstarek
¿Puede hacer que el número de líneas sea variable, de modo que la llamada sea algo así como: head_ tail (foo, m, n), devolviendo las primeras m y últimas n líneas de texto?
ricardo
@ricardo que implicaría escribir un script bash que toma 3 argumentos y los pasa a taily heado una función por alias-Ing ella.
Esto funciona para archivos de longitud conocida, pero no para archivos cuya longitud es desconocida.
Kevin
0
Para manejar tuberías (streams) así como archivos, agregue esto a su archivo .bashrc o .profile:
headtail(){ awk -v offset="$1"'{ if (NR <= offset) print; else { a[NR] = $0; delete a[NR-offset] } } END { for (i=NR-offset+1; i<=NR; i++) print a[i] }';}
Entonces no solo puedes
headtail 10< file.txt
pero también
a.out | headtail 10
(Esto todavía agrega líneas en blanco espurias cuando 10 excede la longitud de la entrada, a diferencia de la anterior a.out | (head; tail). Gracias, respondedores anteriores).
Sobre la base de lo que @Samus_ explicó aquí sobre cómo funciona el comando de @Aleksandra Zalcman, esta variación es útil cuando no se puede detectar rápidamente dónde comienza la cola sin contar líneas.
Yo diría que dependiendo del tamaño del archivo, leer activamente en su contenido puede no ser deseable. En esa circunstancia, creo que deberían bastar algunas secuencias de comandos de shell simples.
Así es como recientemente manejé esto para varios archivos CSV muy grandes que estaba analizando:
$ for file in*.csv;do echo "### ${file}"&& head ${file}&& echo ...&& tail ${file}&& echo;done
Esto imprime las primeras 10 líneas y las últimas 10 líneas de cada archivo, al tiempo que imprime el nombre de archivo y algunos puntos suspensivos antes y después.
Para un solo archivo grande, simplemente puede ejecutar lo siguiente para obtener el mismo efecto:
$ head somefile.csv && echo ...&& tail somefile.csv
Respuestas:
Puedes simplemente:
Y si necesita usar tuberías por alguna razón, entonces así:
Nota: imprimirá líneas duplicadas si el número de líneas en file.txt es menor que las líneas predeterminadas de encabezado + líneas predeterminadas de cola.
fuente
head
haber consumido las primeras 10 líneas del archivo. (Compare esto conhead < file.txt; tail < file.txt
un archivo con menos de 20 líneas). Solo un punto muy pequeño a tener en cuenta. (Pero aún así +1.)head
solo muestra las primeras 10 líneas de su entrada, no se garantiza que no haya consumido más para encontrar el final de la décima línea, dejando menos de la entrada paraless
mostrar.seq 100 | (head; tail)
me da solo los primeros 10 números. Solo en un tamaño de entrada mucho más grande (comoseq 2000
) la cola recibe algo de entrada.ed
es elstandard text editor
fuente
sed
aed
Para una secuencia pura (por ejemplo, salida de un comando), puede usar 'tee' para bifurcar la secuencia y enviar una secuencia a la cabeza y otra a la cola. Esto requiere el uso de la función '> (lista)' de bash (+ / dev / fd / N):
o usando / dev / fd / N (o / dev / stderr) más subcapas con redireccionamiento complicado:
(Ninguno de estos funcionará en csh o tcsh).
Para algo con un poco de mejor control, puede usar este comando perl:
fuente
COMMAND | { tee >(head >&2) | tail; } |& other_commands
cat >/dev/null
lo corrige:COMMAND | { tee >(head >&2; cat >/dev/null) | tail; } |& other_commands
head
ytail
comandos: \ ...Solo otra variación del
(head;tail)
tema, pero evitando el problema inicial de llenado del búfer para archivos pequeños.fuente
head -10 file.txt; tail -10 file.txt
Aparte de eso, necesitarás escribir tu propio programa / script.
fuente
cat
y /head
otail
entubado, ¡es bueno saber que puedo usarlos individualmente!{ head file; tail file; } | prog
(espaciado dentro de las llaves, y el punto y coma final son obligatorios)Basado en el comentario de JF Sebastian :
De esta manera, puede procesar la primera línea y el resto de manera diferente en una sola tubería, lo que es útil para trabajar con datos CSV:
fuente
El problema aquí es que los programas orientados a secuencias no conocen de antemano la longitud del archivo (porque puede que no haya uno, si es una secuencia real).
herramientas como
tail
almacenar las últimas n líneas vistas y esperar el final de la transmisión, luego imprimir.si desea hacer esto en un solo comando (y hacer que funcione con cualquier desplazamiento, y no repita líneas si se superponen) tendrá que emular este comportamiento que mencioné.
prueba este awk:
fuente
a.out | awk -v ...
Me llevó mucho tiempo terminar con esta solución, que parece ser la única que cubrió todos los casos de uso (hasta ahora):
Lista de características:
fuente
He estado buscando esta solución por un tiempo. Lo intenté yo mismo con sed, pero el problema de no saber de antemano la longitud del archivo / flujo era insuperable. De todas las opciones disponibles anteriormente, me gusta la solución awk de Camille Goudeseune. Él hizo una nota de que su solución dejaba líneas en blanco adicionales en la salida con un conjunto de datos suficientemente pequeño. Aquí proporciono una modificación de su solución que elimina las líneas adicionales.
fuente
Bueno, siempre puedes encadenarlos juntos. Me gusta así
head fiename_foo && tail filename_foo
. Si eso no es suficiente, puede escribir una función bash en su archivo .profile o en cualquier archivo de inicio de sesión que utilice:Y, más tarde invocarla desde el shell de comandos:
head_and_tail filename_foo
.fuente
Primeras 10 líneas de archivo.ext, luego sus últimas 10 líneas:
cat file.ext | head -10 && cat file.ext | tail -10
Últimas 10 líneas del archivo, luego las primeras 10:
cat file.ext | tail -10 && cat file.ext | head -10
Luego puede canalizar la salida en otro lugar también:
(cat file.ext | head -10 && cat file.ext | tail -10 ) | your_program
fuente
tail
yhead
o una función por alias-Ing ella.Escribí una aplicación simple de Python para hacer esto: https://gist.github.com/garyvdm/9970522
Maneja tuberías (flujos) y archivos.
fuente
aprovechando las ideas anteriores (probado bash y zsh)
pero usando un alias 'hat' Head and Tails
fuente
¿Por qué no usar
sed
para esta tarea?sed -n -e 1,+9p -e 190,+9p textfile.txt
fuente
Para manejar tuberías (streams) así como archivos, agregue esto a su archivo .bashrc o .profile:
Entonces no solo puedes
pero también
(Esto todavía agrega líneas en blanco espurias cuando 10 excede la longitud de la entrada, a diferencia de la anterior
a.out | (head; tail)
. Gracias, respondedores anteriores).Nota:
headtail 10
noheadtail -10
.fuente
Sobre la base de lo que @Samus_ explicó aquí sobre cómo funciona el comando de @Aleksandra Zalcman, esta variación es útil cuando no se puede detectar rápidamente dónde comienza la cola sin contar líneas.
O si comienza a trabajar con algo más que 20 líneas, un recuento de líneas podría incluso ayudar.
fuente
Para imprimir las primeras 10 y últimas 10 líneas de un archivo, puede intentar esto:
cat <(head -n10 file.txt) <(tail -n10 file.txt) | less
fuente
NOTA : La variable aFile contiene la ruta completa del archivo .
fuente
Yo diría que dependiendo del tamaño del archivo, leer activamente en su contenido puede no ser deseable. En esa circunstancia, creo que deberían bastar algunas secuencias de comandos de shell simples.
Así es como recientemente manejé esto para varios archivos CSV muy grandes que estaba analizando:
Esto imprime las primeras 10 líneas y las últimas 10 líneas de cada archivo, al tiempo que imprime el nombre de archivo y algunos puntos suspensivos antes y después.
Para un solo archivo grande, simplemente puede ejecutar lo siguiente para obtener el mismo efecto:
fuente
Consume stdin, pero simple y funciona para el 99% de los casos de uso
cabeza y cola
ejemplo
fuente