script example ejemplos bash shell unix sed stdout

example - bash script execute command



Shell/Bash Command para obtener la enésima línea de STDOUT (13)

¿Hay algún comando bash que te permita obtener la enésima línea de STDOUT?

Es decir, algo que tomaría esto

$ ls -l -rw-r--r--@ 1 root wheel my.txt -rw-r--r--@ 1 root wheel files.txt -rw-r--r--@ 1 root wheel here.txt

y haz algo como

$ ls -l | magic-command 2 -rw-r--r--@ 1 root wheel files.txt

Me doy cuenta de que esto sería una mala práctica al escribir scripts destinados a ser reutilizados, PERO cuando trabaje con el shell día a día sería útil para mí poder filtrar mi STDOUT de esa manera.

También me doy cuenta de que esto sería un comando semi-trivial para escribir (buffer STDOUT, devolver una línea específica), pero quiero saber si hay algún comando de shell estándar para hacer esto que estaría disponible sin que yo coloque un script en su lugar.


¿Perl está fácilmente disponible para ti?

$ perl -n -e ''if ($. == 7) { print; exit(0); }''

Obviamente, sustituye el número que quieras por 7.


Agregué esto en mi .bash_profile

function gdf(){ DELETE_FILE_PATH=$(git log --diff-filter=D --summary | grep delete | grep $1 | awk ''{print $4}'') SHA=$(git log --all -- $DELETE_FILE_PATH | grep commit | head -n 1 | awk ''{print $2}'') git show $SHA -- $DELETE_FILE_PATH }

Y es obras

gdf <file name>


Alternativa a la buena forma de cabeza / cola:

ls -al | awk ''NR==2''

o

ls -al | sed -n ''2p''


De sed1line :

# print line number 52 sed -n ''52p'' # method 1 sed ''52!d'' # method 2 sed ''52q;d'' # method 3, efficient on large files

Desde awk1line :

# print line number 52 awk ''NR==52'' awk ''NR==52 {print;exit}'' # more efficient on large files


En aras de la exhaustividad ;-)

código más corto

find / | awk NR==3

vida más corta

find / | awk ''NR==3 {print $0; exit}''


Hmm

sed no funcionó en mi caso. Propongo:

para líneas "impares" 1,3,5,7 ... ls | awk ''0 == (NR + 1)% 2''

para líneas "pares" 2,4,6,8 ls | awk ''0 == (NR)% 2''


Otro póster sugerido

ls -l | head -2 | tail -1

pero si canalizas la cabeza hacia la cola, parece que todo hasta la línea N se procesa dos veces.

Tubería de cola en la cabeza

ls -l | tail -n +2 | head -n1

sería más eficiente?


Para mayor completud ...

ls -l | (for ((x=0;x<2;x++)) ; do read ; done ; head -n1)

Tira las líneas hasta llegar al segundo, luego imprime la primera línea después de eso. Entonces, imprime la tercera línea.

Si es solo la segunda línea ...

ls -l | (read; head -n1)

Pon tantas ''lecturas como sea necesario.


Prueba esta versión sed :

ls -l | sed ''2 ! d''

Dice "eliminar todas las líneas que no son la segunda".


Puedes usar awk:

ls -l | awk ''NR==2''

Actualizar

El código anterior no obtendrá lo que queremos debido a un error "uno por uno": la primera línea del comando ls -l es la línea total . Para eso, el siguiente código revisado funcionará:

ls -l | awk ''NR==3''


Sí, la forma más eficiente (como ya señaló Jonathan Leffler) es utilizar sed con print & quit:

set -o pipefail # cf. help set time -p ls -l | sed -n -e ''2{p;q;}'' # only print the second line & quit (on Mac OS X) echo "$?: ${PIPESTATUS[*]}" # cf. man bash | less -p ''PIPESTATUS''


Usando sed , solo por variedad:

ls -l | sed -n 2p

El uso de esta alternativa, que parece más eficiente ya que deja de leer la entrada cuando se imprime la línea requerida, puede generar un SIGPIPE en el proceso de alimentación, que a su vez puede generar un mensaje de error no deseado:

ls -l | sed -n -e ''2{p;q}''

Lo he visto con suficiente frecuencia como para usar el primero (que es más fácil de escribir, de todos modos), aunque ls no es un comando que se queja cuando se convierte en SIGPIPE.

Para una variedad de líneas:

ls -l | sed -n 2,4p

Para varios rangos de líneas:

ls -l | sed -n -e 2,4p -e 20,30p ls -l | sed -n -e ''2,4p;20,30p''


ls -l | head -2 | tail -1