Respuestas:
Aquí hay una manera que utiliza la expansión de parámetros bash y su IFS
variable especial.
$ System=('s1' 's2' 's3' 's4 4 4')
$ ( IFS=$'\n'; echo "${System[*]}" )
Usamos un subshell para evitar sobrescribir el valor de IFS
en el entorno actual. En ese subshell, modificamos el valor de IFS
modo que el primer carácter sea una nueva línea (usando $'...'
comillas). Finalmente, usamos la expansión de parámetros para imprimir el contenido de la matriz como una sola palabra; cada elemento está separado por el primer personaje de IFS
.
Para capturar a una variable:
$ var=$( IFS=$'\n'; echo "${System[*]}" )
Si su bash es lo suficientemente nuevo (4.2 o posterior), aún puede (y debería) usarlo printf
con la -v
opción:
$ printf -v var "%s\n" "${System[@]}"
En cualquier caso, es posible que no desee la nueva línea final var
. Para eliminarlo:
$ var=${var%?} # Remove the final character of var
var=${var%?}
? Esta no es una expresión regular, por .
lo que solo coincidirá con un carácter de punto.
$ IFS=', ' $ echo ${VAR[*]} first second third $ echo "${VAR[*]}" first,second,third
awk -v sep='\n' 'BEGIN{ORS=OFS="";for(i=1;i<ARGC;i++){print ARGV[i],ARGC-i-1?sep:""}}' "${arr[@]}"
o
perl -le 'print join "\n",@ARGV' "${arr[@]}"
o
python -c 'import sys;print "\n".join(sys.argv[1:])' "${arr[@]}"
o
sh -c 'IFS=$'\''\n'\'';echo "$*"' '' "${arr[@]}"
o
lua <(echo 'print(table.concat(arg,"\n"))') "${arr[@]}"
o
tclsh <(echo 'puts [join $argv "\n"]') "${arr[@]}"
o
php -r 'echo implode("\n",array_slice($argv,1));' -- "${arr[@]}"
o
ruby -e 'puts ARGV.join("\n")' "${arr[@]}"
eso es todo lo que puedo recordar hasta ahora.
Las soluciones anteriores son más o menos eso, pero la pregunta original pide resultados para archivar:
$ a=(a b c d e)
$ ( IFS=$'\n'; echo "${a[*]}" ) > /tmp/file
$ cat /tmp/file
a
b
c
d
e
$
Notas: 1) 'echo' proporciona la nueva línea final 2) Si bash vuelve a leer este archivo nuevamente, entonces declare -p puede ser la serialización deseada.
Utilizando para :
for each in "${alpha[@]}"
do
echo "$each"
done
Usando la historia ; tenga en cuenta que esto fallará si sus valores contienen !
:
history -p "${alpha[@]}"
Usando basename ; tenga en cuenta que esto fallará si sus valores contienen /
:
basename -a "${alpha[@]}"
Usando shuf ; tenga en cuenta que los resultados pueden no aparecer en orden:
shuf -e "${alpha[@]}"
Mi opinión , usando solo Bash Builtins, sin mutar IFS
:
# $1 separator
# $2… strings
join_strings () {
declare separator="$1";
declare -a args=("${@:2}");
declare result;
printf -v result '%s' "${args[@]/#/$separator}";
printf '%s' "${result:${#separator}}"
}
$ join_strings $'\n' "a b c" "d e f" "g h i"
a b c
d e f
g h i
También puedes usar cualquier separador:
$ join_strings '===' "a b c" "d e f" "g h i"
a b c===d e f===g h i
printf
parece ser el enfoque más eficiente para crear una cadena delimitada a partir de una matriz:
# create a delimited string; note that printf doesn't put the trailing delimiter
# need to save and restore IFS
# it is prudent to put the whole logic on a single line so as to minimize the risk of future code changes breaking the sequence of saving/restoring of IFS
oldIFS=$IFS; IFS=$'\n'; printf -v var "${arr[*]}"; IFS=$oldIFS
# print string to file; note that the newline is required in the format string because printf wouldn't put a trailing delimiter (which is a good thing)
printf '%s\n' "$var" > file
Una forma aún más simple de hacer esto es:
delim=$'\n'
printf -v var "%s$delim" "${arr[@]}" # create a delimited string
var="${var%$delim}" # remove the trailing delimiter
delim=:
arr=(one two three)
printf -v var "%s$delim" "${arr[@]}" # yields one:two:three:
var="${var%$delim}" # yields one:two_three