Estoy tratando de obtener una línea específica de un archivo de texto.
Hasta ahora, en línea solo he visto cosas como sed, (solo puedo usar sh -not bash o sed ni nada por el estilo). Necesito hacer esto solo usando un script de shell básico.
cat file | while read line
do
#do something
done
Sé cómo iterar a través de las líneas, como se muestra arriba, pero ¿qué pasa si solo necesito obtener el contenido de una línea en particular?

catbien perosedno? Eso no tiene sentido.cat. ¡Oh ... lindocat!Respuestas:
sed:
awk:
fuente
5!dsignifica eliminar todas las líneas excepto 5. shell var es posible, necesita comillas dobles.sed -n 5pesto parece más lógico de recordar para los principiantes, porque-nsignifica "sin salida por defecto" ypsignifica "imprimir", y no hay una mención potencialmente confusa de eliminar (cuando la gente habla de archivos, eliminar líneas tiende a significa algo diferente).-n '5p'funciona para este problema. La diferencia aquí es5!dque puede agregar-ipara volver a escribir el cambio en el archivo. sin embargo,-n 5ptengo quesed -n '5p' f > f2&& mv f2 fvolver a hacerlo , para esta pregunta, estoy de acuerdo con su opinión.Suponiendo que
linees una variable que contiene su número de línea requerido, si puede usarheadytail, entonces es bastante simple:Si no, esto debería funcionar:
fuente
-eqcomparación es para enteros, por lo que quiere un número de línea, no contenido de línea ($line). Esto debe solucionarse definiendo, por ejemplo,want=5antes del bucle y luego utilizando la-eqcomparación en$want. [movido de una edición rechazada]Podrías usar
sed -n 5p file.También puede obtener un rango, por ejemplo,
sed -n 5,10p file.fuente
Mejor método de rendimiento
Porque
seddeja de leer cualquier línea después de la quinta.Actualizar el experimento del Sr. Roger Dueck
fuente
sed -n 5qseddeja de leer las líneas después de la quinta.sed -n 1p /usr/share/dict/wordsysed '1q;d' /usr/share/dict/wordsutilizando eltimecomando; el primero tomó 0.043s, el segundo solo 0.002s, por lo que usar 'q' es definitivamente una mejora del rendimiento.Si, por ejemplo, desea obtener las líneas 10 a 20 de un archivo, puede utilizar cada uno de estos dos métodos:
o
pen el comando anterior significa impresión.Esto es lo que verá:
fuente
La forma estándar de hacer este tipo de cosas es utilizar herramientas externas. No permitir el uso de herramientas externas mientras se escribe un script de shell es absurdo. Sin embargo, si realmente no desea utilizar herramientas externas, puede imprimir la línea 5 con:
Tenga en cuenta que esto imprimirá la línea lógica 5. Es decir, si
input-filecontiene continuaciones de línea, se contarán como una sola línea. Puede cambiar este comportamiento agregando-ral comando de lectura. (Que es probablemente el comportamiento deseado).fuente
$((++i))parece ser un bashismo; si el OP está restringido en el uso de herramientas externas, no asumiría que tendrán acceso a más de un simple/bin/sh++incrementos está específicamente marcado como opcional).$((i+=1))funciona en Dash también.$(($i+1))es la solución simple en la que estaba pensando.En paralelo con la respuesta de William Pursell , aquí hay una construcción simple que debería funcionar incluso en el shell Bourne v7 original (y, por lo tanto, también en lugares donde Bash no está disponible).
Nótese también la optimización para
breaksalir del ciclo cuando hemos obtenido la línea que estábamos buscando.fuente
No me gustó particularmente ninguna de las respuestas.
Así es como lo hice.
fuente
¡Fácil con perl! Si desea obtener las líneas 1, 3 y 5 de un archivo, diga / etc / passwd:
fuente
seq 5 | perl -ne 'print if $. ~~ [1, 4, 5]'pero smartmatch es experimental y se desaconseja su usofuente
sed -n 5pque, por supuesto, aún se puede optimizar a algo comosed -n '5!d;p;q'