bash - substitui o espaço por uma nova linha

56

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

Nota

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:

Pergunta relacionada

Como posso encontrar e substituir por uma nova linha?

    
por laconbass 17.12.2013 / 16:27

9 respostas

103

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

    
por 17.12.2013 / 16:27
16

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.

    
por 17.12.2013 / 17:25
5

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 …
    
por 18.12.2013 / 01:24
4

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.

    
por 29.04.2017 / 19:24
3

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'
    
por 17.12.2013 / 17:28
0

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 .

    
por 17.12.2013 / 16:32
0

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.

    
por 17.12.2013 / 16:40
0
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.

    
por 29.04.2017 / 19:36
-3

O script a seguir é fácil de entender e fácil de usar.

cat filename | tr ' ' '\n' | tee filename
    
por 03.09.2015 / 07:59