Existe algum comando bash que permita obter a enésima linha do STDOUT?
Ou seja, algo que levaria isso
$ 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
e fazer algo como
$ ls -l | magic-command 2
-rw-r--r--@ 1 root wheel files.txt
Sei que isso seria uma prática ruim ao escrever scripts que deveriam ser reutilizados, mas, ao trabalhar com o shell dia a dia, seria útil para mim filtrar meu STDOUT dessa maneira.
Também sei que seria um comando semi-trivial para escrever (buffer STDOUT, retorne uma linha específica), mas quero saber se existe algum comando shell padrão para fazer isso que estaria disponível sem que eu colocasse um script no lugar.
magic-command
Respostas:
Usando
sed
, apenas pela variedade:O uso dessa alternativa, que parece mais eficiente, pois para de ler a entrada quando a linha necessária é impressa, pode gerar um SIGPIPE no processo de alimentação, o que, por sua vez, pode gerar uma mensagem de erro indesejada:
Eu já vi com bastante frequência que geralmente uso o primeiro (que é mais fácil de digitar), embora
ls
não seja um comando que reclama quando obtém o SIGPIPE.Para várias linhas:
Para vários intervalos de linhas:
fonte
p
é ased
declaração que imprime as linhas identificadas pelo intervalo de linhas que a precede. Assim,2,4p
significa que as linhas de impressão 2, 3, 4.n
significa NÃO imprimir todas as outras linhasfonte
head -n 2 | tail -n 1
- caras e coroas modernas tendem a emitir avisos de outra forma.head -n M | tail -n M-N+1
), e a generalização para lidar com vários intervalos não é possível.$ ls -l | awk '{if (NR>=4 && NR<=64) print}'
(pode adicionar mais condições mais fáceis, vários intervalos, etc ...)Alternativa para o bom caminho da cabeça / cauda:
ou
fonte
'2p'
significa?2
for uma variável? Cada exemplo usa aspas simples, mas com um var você precisa de aspas duplas. Poderíamos "programar" o awk para trabalhar também com aspas simples ao usar vars? Exemploline =1; ls | awk 'NR==$line'
. Eu sei quebash
usa aspas duplas com vars.Do sed1line :
Do awk1line :
fonte
Por uma questão de completude ;-)
código mais curto
vida mais curta
fonte
ls
- a pergunta original era sobre alguémSTDOUT
, então eu pensei que era melhor tê-lo maior.{ print $0 }
, portanto, `awk 'NR == 3' é uma maneira mais curta de escrever o mesmo.Experimente esta
sed
versão:Ele diz "exclua todas as linhas que não são a segunda".
fonte
Você pode usar o awk:
Atualizar
O código acima não conseguirá o que queremos devido a um erro de um por um: a primeira linha do comando ls -l é a linha total . Para isso, o seguinte código revisado funcionará:
fonte
Perl está facilmente disponível para você?
Substitua, obviamente, o número que desejar para 7.
fonte
$ awk 'NR % 7' filename
para imprimir todas as 7ª linhas do arquivo.Outro pôster sugerido
mas se você enfiar a cabeça na cauda, parece que tudo até a linha N é processado duas vezes.
Tubulação de cauda na cabeça
seria mais eficiente?
fonte
Sim, a maneira mais eficiente (como já apontado por Jonathan Leffler) é usar o sed com print & quit:
fonte
Hmm
sed não funcionou no meu caso. Eu proponho:
fonte
Para mais perfeição ..
Jogue fora as linhas até chegar à segunda e depois imprima a primeira linha. Então, imprime a terceira linha.
Se é apenas a segunda linha ..
Coloque quantas leituras forem necessárias.
fonte
Adicionei isso no meu .bash_profile
E é obras
fonte