Repete todos os argumentos em um script de shell [duplicado]

0

Eu criei um script de shell, mas não sei como fazer um loop que imprime o número de linhas em cada arquivo que você passa para o script como argumento. Para que a saída seja algo assim:

2 lines in hello.sh
33 lines in /var/log/syslog
    
por Alessa 14.05.2018 / 23:20

4 respostas

2

Assumindo um shell POSIX, você quer um loop for aqui, passando por cima de "$@" , que contém os argumentos da linha de comando:

for filename in "$@"; do
    lines=$(wc -l < "$filename")
    printf '%u lines in %s\n' "$lines" "$filename"
done

Usar todas as citações é muito importante. Ele permite que você passe nomes de arquivos que contenham espaços e outros caracteres.

./my_script.sh /var/log/syslog "$HOME/My Dir with Spaces/a file with spaces.txt"
    
por 14.05.2018 / 23:28
2

Em geral, para fazer um loop sobre o argumento da linha de comando em um script ou função shell, você pode fazer

for thing do
    commands using "$thing"
done

ou

for thing in "$@"; do
    commands using "$thing"
done

Nesse caso, supondo que os nomes de arquivos fornecidos na linha de comando não contenham novas linhas literais, não é necessário fazer um loop de shell explícito para isso:

wc -l -- "$@" | sed -E '$d;s/^[[:blank:]]*([[:digit:]]*)[[:blank:]]*(.*)/ lines in /'

Isso levaria todos os argumentos da linha de comando e executaria wc -l em todos eles.

A saída é analisada por sed , que descarta a última linha contendo o número total de linhas nos arquivos fornecidos (usando $d ). O restante da saída de wc -l é transformado na saída que você deseja, capturando o número de linhas e o nome do arquivo e, em seguida, inserindo a string lines in no meio.

A execução do script com meus próprios arquivos .vimrc , .profile e .mailrc retornará

8 lines in .vimrc
8 lines in .profile
4 lines in .mailrc

Observe que wc -l -- "$@" criará resultados como

   8 .vimrc
   8 .profile
   4 .mailrc
  20 total

que pode realmente ser suficiente para o que você deseja, sem a necessidade de sed .

    
por 15.05.2018 / 08:15
0
#!/bin/bash

for file in "${@}"; do
    wc -l -- "${file}"
done

#!/bin/bash Programa que executará este script.

${@} Argumentos posicionais. Argumentos que você fornece ao script por meio da linha de comando.

file Variável que irá iterar sobre os argumentos dados em ${@} .

wc -l -- "${file}" Comando externo que imprimirá o número de linhas em ${file} (exceto quando ${file} for - , nesse caso, imprimirá o número de linhas em sua entrada padrão).

    
por 14.05.2018 / 23:27
0

Alternativa usando while e shift

while [ $# -gt 0 ] ; do
    printf '%u lines in %s\n' $(wc -l < "$1") "$1"
    shift
done
    
por 26.11.2018 / 02:09