2010-03-13 20 views

Respuesta

249

head toma las primeras líneas de un archivo, y el parámetro -n puede usarse para especificar el número de líneas que debe extraerse:

line=$(head -n 1 filename) 
+1

Significativamente más gastos generales que el enfoque de 'lectura '. '$()' sobrescribe una subcadena, y el uso de un comando externo (* cualquier * comando externo) significa que está llamando a 'execve()', invocando el enlazador y el cargador (si usa bibliotecas compartidas, que generalmente es el caso), etc. –

+1

Podría ser aún más corto: 'line =" $ (head -1 FILENAME) "' – nikolay

+0

Y también: 'line = \' head -1 FILENAME \ ' –

9
line=$(head -1 file) 

no tendrán ningún problema. (Como respuesta anterior). Pero

line=$(read -r FIRSTLINE < filename) 

habrá marginalmente más rápido que read es un comando incorporado en bash.

+17

El segundo método no funciona como está escrito , porque 'leer' no imprime nada (entonces' line' termina en blanco), y también se ejecuta en una subcadena (por lo que 'FIRSTLINE' se establece en la primera línea, pero solo en la subshell, por lo que no está disponible después) .Solución: simplemente use 'read -r line

35

para leer la primera línea usando bash, use la instrucción read. por ejemplo

read -r firstline<file 

firstline será su variable (No hay necesidad de asignar a otro)

+0

intentado con' cat ... | lea -r VAR' y falla :( – sorin

+0

¿Cómo lee la segunda línea? – qed

+1

@sorin, 'cat ... | read VAR' fallará en la mayoría de shells (excepto' zsh', por lo que sé) porque cada uno de los componentes de una tubería se ejecutará en subcapas separadas, lo que significa que '$ VAR' se establecerá en subshell (que dejará de existir tan pronto como la tubería haya terminado de ejecutarse) en lugar de en la capa invocadora. Puede evitar esto con 'leer VAR << EOF \ n $ (cat ...) \ nEOF' (donde cada' \ n' es una nueva línea). – zrajm

8

Esto es suficiente y almacena la primera línea de filename en la variable $line:

read -r line < filename 

También me gusta awk para esto:

awk 'NR==1 {print; exit}' file 

Para almacenar la línea, use la sintaxis var=$(command). En este caso, line=$(awk 'NR==1 {print; exit}' file).

O incluso sed:

sed -n '1p' file 

Con el equivalente line=$(sed -n '1p' file).


Ver una muestra cuando damos de comer al read con seq 10, es decir, una secuencia de números del 1 al 10:

$ read -r line < <(seq 10) 
$ echo "$line" 
1 

$ line=$(awk 'NR==1 {print; exit}' <(seq 10)) 
$ echo "$line" 
1 
+1

' sed '1! D; q'' (o 'sed -n '1p; q'') imitará su 'awk' logi c e impiden leer más en el archivo. Como solo queremos la primera línea, alternativamente podemos hacer trampa con 'sed q' o' awk '1; {exit}'' o incluso 'grep -m1 ^' (menos código, la misma lógica esencial). (Esta no es una respuesta a la consulta de downvote.) –

+0

@ AdamKatz es una muy buena serie de formas, ¡gracias! Encuentro el que tiene 'grep' muy inteligente. Por supuesto, también podemos decir 'head -n 1 file'. – fedorqui

+0

Sí, 'head -n1' será más rápido (binario más pequeño para cargar) y' read' será más rápido (no binario para cargar, eso es un builtin). Me gusta especialmente 'grep -m1 --color .' cuando estoy imprimiendo la primera línea porque también coloreará la línea, lo que lo hace ideal para los encabezados de las tablas. –

4

La pregunta no le preguntó que es más rápido, pero para agregar para la respuesta sed, -n '1p' está funcionando mal ya que el espacio del patrón aún se escanea en archivos grandes. Por curiosidad he encontrado que 'cabeza' gana más estrecho SED:

# best: 
head -n1 $bigfile >/dev/null 

# a bit slower than head (I saw about 10% difference): 
sed '1q' $bigfile >/dev/null 

# VERY slow: 
sed -n '1p' $bigfile >/dev/null 
3

Sólo echo la primera lista de su archivo de origen en el archivo de destino.

echo $(head -n 1 source.txt) > target.txt 
+1

Para lo cual 'head -n 1 source.txt> target.txt' logrará exactamente lo mismo. – YoYo

Cuestiones relacionadas