Imprimir uma matriz em um arquivo com cada elemento da matriz em uma nova linha no bash


13

Estou tentando o conteúdo de uma matriz em um arquivo com cada elemento da matriz em uma nova linha no arquivo.

IFS=$'\n'   
echo "${mtches[@]}" > sample1.txt 


O conteúdo de mtches é "qwe" e "asd". Mas o sample1.txtarquivo contém qwe asdem uma única linha. Por que não está levando em consideração o valor do IFS?

Respostas:


16

Você deve usar em printfvez deecho :

printf "%s\n" "${mtches[@]}"

Se mtchesestiver vazio, isso ainda produziria uma linha vazia. Para explicar isso:

{ [ "${#mtches[@]}" -eq 0 ] || printf '%s\n' "${mtches[@]}"; } > file

Em bash(e também em shells POSIX), você geralmente usa a matriz Parâmetros Posicionais em "$@"vez de "$*", a menos que tenha um motivo especial. Isso também é verdade em shells que suportam matrizes regulares, do man bash - section Matrizes :

Qualquer elemento de uma matriz pode ser referenciado usando $ {name [subscript]}. Os colchetes são necessários para evitar conflitos com os operadores de expansão de nome de arquivo do shell. Se o subscrito for '@' ou '*', a palavra se expandirá para todos os membros do nome da matriz. Esses subscritos diferem apenas quando a palavra aparece entre aspas duplas. Se a palavra estiver entre aspas duplas, $ {name [*]} será expandida para uma única palavra com o valor de cada membro da matriz separado pelo primeiro caractere da variável IFS, e $ {name [@]} expandirá cada elemento do nome para uma palavra separada. Quando não há membros da matriz, $ {name [@]} se expande para nada. Se a expansão entre aspas ocorrer em uma palavra, a expansão do primeiro parâmetro será associada à parte inicial da palavra original e a expansão do último parâmetro será associada à última parte da palavra original.

Use somente "${array[*]}"quando desejar associar todos os elementos da matriz a uma sequência.


Como isso faz diferença?
Ashwin


7

Você deseja usar em seu ${mtches[*]}lugar.

Quando você usa "${mtches[@]}", não importa qual é o valor $IFS, o bash dividirá a matriz em vários argumentos. O que você deseja é um único argumento com cada elemento do array associado \n. ${mtches[*]}realiza isso.

Também como forma temporária de configuração $IFS, você pode:

( IFS=$'\n'; echo "${mtches[*]}" > sample1.txt )

Então você não precisa se preocupar em configurá-lo de volta.


pubs.opengroup.org/onlinepubs/9699919799/utilities/… <- referência POSIX (isso não se aplica apenas ao bash).
Mat

Ou use printf...
jasonwryan

2

Usando para :

for each in "${alpha[@]}"
do
  echo "$each"
done

Usando história ; observe que isso falhará se seus valores contiverem !:

history -p "${alpha[@]}"

Usando o basename ; observe que isso falhará se seus valores contiverem /:

basename -a "${alpha[@]}"

Usando shuf ; observe que os resultados podem não sair em ordem:

shuf -e "${alpha[@]}"

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.