文件名中的空格问题

use*_*532 8 command-line

我想在文件列表上重复做一些事情。问题中的文件名称中有空格:

david@david: ls -l
total 32
-rw-rw-r-- 1 david david 13 Mai  8 11:55 haha
-rw-rw-r-- 1 david david  0 Mai  8 11:55 haha~
-rw-rw-r-- 1 david david 13 Mai  8 11:55 haha (3rd copy)
-rw-rw-r-- 1 david david 13 Mai  8 11:55 haha (4th copy)
-rw-rw-r-- 1 david david 13 Mai  8 11:55 haha (5th copy)
-rw-rw-r-- 1 david david 13 Mai  8 11:55 haha (6th copy)
-rw-rw-r-- 1 david david 13 Mai  8 11:55 haha (7th copy)
-rw-rw-r-- 1 david david 13 Mai  8 11:55 haha (another copy)
-rw-rw-r-- 1 david david 13 Mai  8 11:55 haha (copy)
Run Code Online (Sandbox Code Playgroud)

现在我想统计这些文件中的每一个:

david@david: echo '
for file in $(ls)
do
stat $file
done' | bash
Run Code Online (Sandbox Code Playgroud)

(我使用 echo 和管道来编写多行命令。)

当我这样做时,它可以在名称中没有任何空格的文件上正常工作。但其他人...

stat: cannot stat ‘(another’: No such file or directory
stat: cannot stat ‘copy)’: No such file or directory
Run Code Online (Sandbox Code Playgroud)

更改$(ls)"$(ls)"$file"$file"不起作用。我能做什么?

编辑:

echo '
for files in *
do
stat "$files"
done' | bash
Run Code Online (Sandbox Code Playgroud)

行得通!因为我是 bash 的新手,所以我想让事情尽可能简单 - 所以没有试图逃避空格,或者使用xargs或 解决方案read -r,尽管它们解决了问题。

正如一些人所问:是的,使用 this 而不是stat *很奇怪。但我只是想找到一种通用方法,使用 for 循环在 bash 中的一堆文件名上应用相同的命令。所以stat可以代表gzip,gpgrm

Rma*_*ano 12

的多引号echo '使事情复杂化。

你可以只使用:

for f in *; do stat -- "$f"; done
Run Code Online (Sandbox Code Playgroud)

但是也

stat -- * 
Run Code Online (Sandbox Code Playgroud)

...如果你想收集文件然后应用命令(为什么?)你可以去(但要小心包含新行的文件......(1))

for f in *; do echo "$f"; done | xargs stat --
Run Code Online (Sandbox Code Playgroud)

...如果您也想要隐藏文件,只需* .*用作模式,但请记住这一点,.并且..将在 set 中

顺便说一句,您不应该解析lsoutput


(1) 但是如果你有带换行符的文件名,你应该得到它...... ;-)

  • @user258532 嗯?为什么你需要回声?只需按 Enter 键并继续换行。如果您以开放引号或`do`、`|`、`&&` 等之一结束一行,则可以在新行上继续。要么使用heredocs。没有理由使用 `echo`,它也会导致问题。 (2认同)

kos*_*kos 6

附带说明:您可以通过添加一个空格后跟一个反斜杠并在Enter每次要开始写入新行时点击来将长/复杂的命令拆分为多行,而不是使用echo [...] | bash; 您还应该$file用双引号括起来,以防止stat在文件名包含空格的情况下中断:

for file in $(ls); \
do \
stat "$file"; \
done
Run Code Online (Sandbox Code Playgroud)

问题是$(ls)扩展到包含空格的文件名列表,同样的情况也会发生在"$(ls)".

即使解决了这个问题,这个方法仍然会在包含反斜杠的文件名和包含换行符的文件名上中断(正如 terdon 所指出的)。

这两个问题的解决方案是将 的输出通过管道find传输到while运行的循环中,read -r以便在每次迭代时read -r将 的一行find输出存储到$file

find . -maxdepth 1 -type f | while read -r file; do \
    stat "$file"; \
done
Run Code Online (Sandbox Code Playgroud)

  • 对于包含换行符的文件名,这仍然会失败。只是不要解析`ls`。曾经。 (5认同)
  • @ user258532 不,不是。说真的,只是 [不要解析`ls`](http://mywiki.wooledge.org/ParsingLs)。有更好、更健壮的方法。您可能还想阅读以下内容:[Why \*not\* parse \`ls\`?](http://unix.stackexchange.com/q/128985) 了解更多详情。 (4认同)