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

12

Eu 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 dos mtches é "qwe" e "asd". Mas o arquivo sample1.txt contém qwe asd em uma única linha. Por que não está levando o valor do IFS para a imagem?

    
por Ashwin 20.04.2014 / 10:44

4 respostas

16

Você deve usar printf em vez de echo :

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

Se mtches estiver vazio, isso ainda produzirá uma linha vazia. Para explicar isso:

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

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

Any element of an array may be referenced using ${name[subscript]}. The braces are required to avoid conflicts with the shell’s filename expansion operators. If the subscript is ‘@’ or ‘*’, the word expands to all members of the array name. These subscripts differ only when the word appears within double quotes. If the word is double-quoted, ${name[*]} expands to a single word with the value of each array member separated by the first character of the IFS variable, and ${name[@]} expands each element of name to a separate word. When there are no array members, ${name[@]} expands to nothing. If the double-quoted expansion occurs within a word, the expansion of the first parameter is joined with the beginning part of the original word, and the expansion of the last parameter is joined with the last part of the original word. This is analogous to the expansion of the special parameters ‘@’ and ‘*’

Use somente "${array[*]}" quando quiser unir todos os elementos do array a uma string.

    
por 20.04.2014 / 10:53
7

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

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

Além disso, como forma temporária de definir $IFS , você pode fazer:

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

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

    
por 20.04.2014 / 10:48
2

Usando para :

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

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

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

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

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

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

shuf -e "${alpha[@]}"
    
por 20.05.2015 / 04:32
1
for ENTRY in ${ARRAY[@]}; do
    echo $ENTRY
done > outfile

Agradável e legível e não significa mexer com o IFS. Isso também significa que você pode personalizar o manuseio de cada linha.

    
por 27.07.2017 / 13:21

Tags