web-dev-qa-db-fra.com

bash - remplacer l'espace par une nouvelle ligne

Comment puis-je remplacer des espaces par de nouvelles lignes sur une entrée comme:

/path/to/file /path/to/file2 /path/to/file3 /path/to/file4 /path/to/file5 etc...

Pour obtenir les éléments suivants:

/path/to/file
/path/to/file2
/path/to/file3
/path/to/file4
/path/to/file5

Remarque

Je poste cette question pour aider d'autres utilisateurs, il n'a pas été facile de trouver une réponse utile sur UNIX SE jusqu'à ce que je commence à taper cette question. Après cela, j'ai trouvé ce qui suit:

Question connexe

Comment puis-je trouver et remplacer par une nouvelle ligne?

84
laconbass

Utilisez la commande tr

echo "/path/to/file /path/to/file2 /path/to/file3 /path/to/file4 /path/to/file5"\
| tr " " "\n"

Trouvé sur http://www.unix.com/Shell-programming-scripting/67831-replace-space-new-line.html

141
laconbass

Dans ce cas, j'utiliserais printf:

printf '%s\n' /path/to/file /path/to/file2 /path/to/file3 /path/to/file4 /path/to/file5

S'il y a des espaces à l'intérieur celui des chemins, vous pouvez citer ce chemin de fichier afin d'éviter qu'il ne soit divisé sur les espaces:

printf '%s\n' /path/to/file '/path/to/file with spaces' /path/to/another/file

Pour transformer le texte en général, tr est votre meilleur pari, comme indiqué dans une réponse existante.

20
evilsoup

Soyez pragmatique, utilisez sed !!

sed 's/\s\+/\n/g' file

Ce qui précède dit de remplacer un ou plusieurs espaces (\ s +) par une nouvelle ligne (\ n)

C'est plus ou moins:

'substitute /one space or more/ for /newline/ globally'
5
MGP

En supposant que vous ayez une chaîne avec des espaces comme séparateurs:

newline_separated=${space_separated// /$'\n'}

Cependant, vous posez probablement la mauvaise question. (Pas nécessairement, par exemple, cela pourrait apparaître dans un makefile.) Une liste de noms de fichiers séparés par des espaces ne fonctionne pas vraiment: que faire si l'un des noms de fichiers contient des espaces?

Si un programme reçoit des noms de fichiers comme arguments, ne les joignez pas à des espaces. Utilisation "$@" pour y accéder un par un. Bien que echo "$@" affiche les arguments avec des espaces entre les deux, c'est dû à echo: il affiche ses arguments avec des espaces comme séparateurs. somecommand "$@" transmet les noms de fichier comme arguments séparés à la commande. Si vous souhaitez imprimer les arguments sur des lignes distinctes, vous pouvez utiliser

printf '%s\n' "$@"

Si vous avez des noms de fichiers séparés par des espaces et que vous souhaitez les placer dans un tableau pour y travailler, vous pouvez utiliser une extension de variable sans guillemets pour diviser la valeur en caractères sur IFS (vous devrez désactiver extension générique avec set -f, sinon les motifs glob seront développés dans la valeur):

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 …

Vous pouvez l'encapsuler dans une fonction qui restaure le -f paramètre et la valeur de IFS quand c'est fait:

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 …

Comme alternative à tr de @laconbass, vous pouvez également utiliser xargs dans ce cas:

echo "/path/to/file /path/to/file2 /path/to/file3 /path/to/file4  /path/to/file5"\
| xargs -n1

L'avantage est qu'il fonctionne même avec plusieurs espaces blancs, ce que tr ne fait pas.

4
FranMowinckel

Voici comment je l'ai fait:

echo "/path/to/file /path/to/file2 /path/to/file3 /path/to/file4 /path/to/file5" | sed 's/ /\
'/g

Notez l'utilisation de la touche Entrée après la barre oblique inverse dans la commande sed.

0
unxnut

Une autre approche, en supposant que la ligne se trouve dans une variable appelée line:

for path in $line;do echo $path;done

Cela utilise le fait que Bash divise ses arguments sur les espaces blancs par défaut et que echo ajoute une nouvelle ligne à son entrée par défaut.

0
Joseph R.
echo Word1 Word2 ... | sed -e 'y/ /\n/;P;D'

est une autre méthode pour transformer des mots séparés par un espace en séparateurs de nouvelle ligne.

0
user218374