Use o comando tr
echo "/path/to/file /path/to/file2 /path/to/file3 /path/to/file4 /path/to/file5"\
| tr " " "\n"
Encontrado no link
Como posso substituir espaços por novas linhas em uma entrada como:
/path/to/file /path/to/file2 /path/to/file3 /path/to/file4 /path/to/file5
etc ...
Para obter o seguinte:
/path/to/file
/path/to/file2
/path/to/file3
/path/to/file4
/path/to/file5
Estou postando esta pergunta para ajudar outros usuários, não foi fácil encontrar uma resposta útil no UNIX SE até que comecei a digitar essa pergunta. Depois disso, encontrei o seguinte:
Use o comando tr
echo "/path/to/file /path/to/file2 /path/to/file3 /path/to/file4 /path/to/file5"\
| tr " " "\n"
Encontrado no link
Neste caso eu usaria printf:
printf '%s\n' /path/to/file /path/to/file2 /path/to/file3 /path/to/file4 /path/to/file5
Se houver espaços dentro de um dos caminhos, você pode citar esse caminho de arquivo para impedir que ele seja dividido nos espaços:
printf '%s\n' /path/to/file '/path/to/file with spaces' /path/to/another/file
Para transformar o texto em geral, tr
é sua melhor aposta, conforme abordado em uma resposta existente.
Supondo que você tenha uma string com espaços como separadores:
newline_separated=${space_separated// /$'\n'}
No entanto, você provavelmente está fazendo a pergunta errada. (Não necessariamente, por exemplo, isso pode aparecer em um makefile.) Uma lista separada por espaços de nomes de arquivos não funciona: e se um dos nomes de arquivos continha espaços?
Se um programa receber nomes de arquivos como argumentos, não se junte a eles com espaços. Use "$@"
para acessá-los um por um. Embora echo "$@"
imprima os argumentos com espaços intermediários, isso é devido a echo
: ele imprime seus argumentos com espaços como separadores. somecommand "$@"
passa os nomes dos arquivos como argumentos separados para o comando. Se você quiser imprimir os argumentos em linhas separadas, você pode usar
printf '%s\n' "$@"
Se você tiver nomes de arquivos separados por espaço e quiser colocá-los em uma matriz para trabalhar neles, poderá usar uma expansão de variável sem aspas para dividir o valor em caracteres em IFS
(você precisará desativar expansão de curinga com set -f
, caso contrário, padrões de glob serão expandidos no valor):
space_separated_list='/path/to/file1 /path/to/file2 /path/to/file3'
IFS=' '; set -f
eval "array=(\$space_separated_list)"
for x in "${array[@]}"; do …
Você pode encapsular isso em uma função que restaura a configuração -f
e o valor de IFS
quando terminar:
split_list () {
local IFS=' ' flags='+f'
if [[ $- = *f* ]]; then flags=; fi
set -f
eval "$1=($2)"
set $flags
}
split_list array '/path/to/file1 /path/to/file2 /path/to/file3'
for x in "${array[@]}"; do …
Como uma alternativa para tr
de @laconbass, você também pode usar xargs
neste caso:
echo "/path/to/file /path/to/file2 /path/to/file3 /path/to/file4 /path/to/file5"\
| xargs -n1
A vantagem é que funciona mesmo com vários espaços em branco, o que tr
não faz.
Seja pragmático, use sed !!
sed 's/\s\+/\n/g' file
O texto acima diz para substituir um ou mais caracteres de espaço em branco (\ s +) por nova linha (\ n)
Isso é mais ou menos:
'substitute /one space or more/ for /newline/ globally'
Veja como eu fiz:
echo "/path/to/file /path/to/file2 /path/to/file3 /path/to/file4 /path/to/file5" | sed 's/ /\
'/g
Observe o uso da tecla Enter após a barra invertida no comando sed
.
Outra abordagem, supondo que a linha esteja em uma variável chamada line
:
for path in $line;do echo $path;done
Isso faz uso do fato de que o Bash divide seus argumentos no espaço em branco por padrão e que echo
acrescenta uma nova linha à sua entrada por padrão.
echo word1 word2 ... | sed -e 'y/ /\n/;P;D'
é outro método para transformar palavras separadas por espaço único em separações de nova linha.
O script a seguir é fácil de entender e fácil de usar.
cat filename | tr ' ' '\n' | tee filename
Tags bash text-processing string