bash - 用新行替换空格

lac*_*ass 120 bash string text-processing

如何在输入中用新行替换空格,例如:

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

要获得以下内容:

/path/to/file
/path/to/file2
/path/to/file3
/path/to/file4
/path/to/file5
Run Code Online (Sandbox Code Playgroud)

笔记

我发布这个问题是为了帮助其他用户,在我开始输入这个问题之前,在 UNIX SE 上找到有用的答案并不容易。之后我发现了以下内容:

相关问题

如何找到并替换新行?

lac*_*ass 192

使用tr命令

echo "/path/to/file /path/to/file2 /path/to/file3 /path/to/file4 /path/to/file5"\
| tr " " "\n"
Run Code Online (Sandbox Code Playgroud)

http://www.unix.com/shell-programming-scripting/67831-replace-space-new-line.html找到

  • +1,但作为评论:如果文件名本身包含空格,那将不起作用 (7认同)
  • @BonsiScott 如果文件名包含空格,整个练习就变得毫无意义。 (2认同)
  • @YoungFrog `sed $'s/ /\\n/g'`。文字换行符必须用反斜杠转义。但 `sed 'y/ /\n/'` 会更快并且更便携。 (2认同)

evi*_*oup 25

在这种情况下,我将使用 printf:

printf '%s\n' /path/to/file /path/to/file2 /path/to/file3 /path/to/file4 /path/to/file5
Run Code Online (Sandbox Code Playgroud)

如果有空格的路径的一个,你可以引述文件路径,以防止它被在空间分割:

printf '%s\n' /path/to/file '/path/to/file with spaces' /path/to/another/file
Run Code Online (Sandbox Code Playgroud)

tr如现有答案中所述,一般地转换文本是您最好的选择。


MGP*_*MGP 11

务实,用sed!!

sed 's/\s\+/\n/g' file
Run Code Online (Sandbox Code Playgroud)

上面说用换行符 (\n) 替换一个或多个空白字符 (\s+)

这或多或少是:

'substitute /one space or more/ for /newline/ globally'
Run Code Online (Sandbox Code Playgroud)

  • 用替代物替换变化,这就是 s 实际代表的意思! (2认同)

Gil*_*il' 9

假设您有一个以空格作为分隔符的字符串:

newline_separated=${space_separated// /$'\n'}
Run Code Online (Sandbox Code Playgroud)

但是,您可能问错了问题。(不一定,例如这可能出现在 makefile 中。)以空格分隔的文件名列表实际上不起作用:如果其中一个文件名包含空格怎么办?

如果程序接收文件名作为参数,不要用空格连接它们。用于"$@"一一访问。虽然echo "$@"打印参数之间有空格,但这是由于echo: 它用空格作为分隔符打印参数。somecommand "$@"将文件名作为单独的参数传递给命令。如果要在单独的行上打印参数,可以使用

printf '%s\n' "$@"
Run Code Online (Sandbox Code Playgroud)

如果您确实有空格分隔的文件名,并且您想将它们放在一个数组中以处理它们,您可以使用不带引号的变量扩展来拆分字符上的值IFS(您需要使用 禁用通配符扩展set -f,否则使用 glob模式将在值中扩展):

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 …
Run Code Online (Sandbox Code Playgroud)

您可以将其封装在一个函数中,该函数恢复-f设置和IFS完成时的值:

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 …
Run Code Online (Sandbox Code Playgroud)


小智 6

作为tr@laconbass的替代方案,您还可以xargs在这种情况下使用:

echo "/path/to/file /path/to/file2 /path/to/file3 /path/to/file4  /path/to/file5"\
| xargs -n1
Run Code Online (Sandbox Code Playgroud)

优点是它甚至可以与多个空格一起使用,而tr事实并非如此。