Posso acessar o número da linha N da saída padrão?

3

Assumindo um script que gera uma lista de arquivos:

$> bash someScript.sh
path/to/some/file
path/to/the/file/i/want/to/work/with
path/to/yet/another/file

Agora quero ter o segundo caminho de arquivo como parâmetro para outro comando, por exemplo, %código%. Existe uma maneira de acessá-lo diretamente?

E quero salientar que não quero necessariamente acessar o segundo arquivo, mas na próxima vez que ele pode ser o terceiro ou o dia 27. Eu quero ser capaz de selecionar essa enésima linha tão facilmente quanto possível.

Agora eu faço seleção de mouse e insiro clicando com o botão do meio ou digite o caminho com conclusão de tabulação. Agora eu me pergunto se existe um jeito mais fácil.

O problema com minha própria solução é que eu teria que editar todos os meus scripts dessa maneira. Seria divertido se houvesse uma solução mais geral para esse problema, que funcionasse com qualquer tipo de comando, por exemplo vim .

    
por k0pernikus 24.01.2012 / 13:18

4 respostas

14

Claro.

bash someScript.sh | sed -n '2 p'

filtrará sua saída e imprimirá a segunda linha dela. Para tornar isso um parâmetro para vim :

vim "$(bash someScript.sh | sed -n '2 p')"
    
por 24.01.2012 / 13:27
2

Use cabeça e cauda, por exemplo acessando a segunda linha de uma saída:

bash someScript.sh | head -2 | tail -1
    
por 24.01.2012 / 13:28
2

Se ser curto para digitar é primordial e o arquivo não é muito grande:

nth_line=$(sed -n ${n}p)
nth_line=$(sed \!${n}d)

Se o arquivo for longo e você estiver interessado apenas em uma linha, use sed para imprimir a linha desejada e saia, ou tail para remover as linhas anteriores e head para extrair a primeira linha da linha resultado.

nth_line=$(sed -n -e "$n {" -e p -e q -e "}")
nth_line=$(tail -n +$n | head -n 1)

(Observe que tail -n +$n ignora as linhas n-1, ou seja, sua saída começa com a enésima linha).

Para um pequeno número de linhas, você pode usar o read incorporado.

IFS= read -r first_line; IFS= read -r second_line

Se você quiser ler todas as linhas, você pode colocá-las em um array (somente ksh / bash / zsh).

IFS=$'\n'
lines=($(cat))
second_file="${lines[1]}"  # note that ksh/bash arrays start at 0

Se você quiser criar esse código reutilizável, coloque-o em uma função.

# Read at most MAX input lines (default: all) into the VAR array (default: ${lines[@]}).
# Usage: read_lines [VAR [MAX]]
read_lines () {
  typeset IFS=$'\n'
  if [ $# -eq 0 ]; then set lines; fi
  if [ -z "$2" ]; then eval "$1=(\$(cat))"; else eval "$1=(\$(head -n $2))"; fi
}
    
por 24.01.2012 / 19:26
0

Eu resolvi isso apesar de ser um pouco hackea;)

Esse é o script que exibe os caminhos dos arquivos:

#!/bin/bash
rm /tmp/svn_filelist_to_source /tmp/svn_filelist
svn status | egrep 'M |A ' | cut -c9- > /tmp/svn_filelist
counter=1
cat /tmp/svn_filelist | while read -r path; do
  echo $path
  echo "file$counter=\"$path\"" >> /tmp/svn_filelist_to_source
  counter=$(($counter+1))
done;

Veja como eu o executo, o que acho que vou colocar em um alias:

sh statusAddedAndModified.sh && source /tmp/svn_filelist_to_source

Agora posso:

svn commit $file2

    
por 24.01.2012 / 14:04