处理特殊字符在bash for ... in循环(Handle special characters

2019-07-23 12:57发布

假设我有一个文件列表

file1
"file 1"
file2

一个for ... in循环打破它的空白之间,不换行:

for x in $( ls ); do
   echo $x
done

结果:

file
1
file1
file2

我想对每个文件执行的命令。 “文件”和“1”上面不是实际的文件。 我该怎么办,如果文件名中包含的东西像空格或逗号?

这是一个有点麻烦,比我想找到-print0 | xargs的-0可以处理,因为我其实希望命令是这样的“转换输入/ file1.jpg ....输出/ file1.jpg”所以我需要排列替换过程中的文件名。

Answer 1:

更新通过OP:这个答案很烂,不应该在上面...... // @下面乔丹的职位应该是公认的答案。

一种可能的方式:

ls -1 | while read x; do
   echo $x
done



Answer 2:

事实上,马克的建议工作,甚至没有做任何内部字段分隔符的罚款。 问题是在子shell中运行LS,无论是反引号或$()会导致for循环是无法在名称中使用空格进行区分。 只需用

for f in *

而不是LS解决了这个问题。

#!/bin/bash
for f in *
do
 echo "$f"
done


Answer 3:

我知道这是一个早已过去“回答”,并与所有尊重eduffy,我想出了一个更好的办法,我想我会分享它。

什么是“错”与eduffy的答案并不在于它是错的,但它规定了什么对我来说是一个痛苦的局限性:有当LS的输出管道子shell的一个隐含的创作,这意味着在循环中设置变量退出循环后丢失。 因此,如果你想写一些更复杂的代码,你必须在臀部疼痛处理。

我的解决办法是采取了“的ReadLine” 功能 ,写一个程序出它在其中您可以指定你可能想要的任何具体的行号从任何给定函数调用的结果。 ......作为一个简单的例子,从eduffy的:

ls_output=$(ls -1)
# The cut at the end of the following line removes any trailing new line character
declare -i line_count=$(echo "$ls_output" | wc -l | cut -d ' ' -f 1)
declare -i cur_line=1 
while [ $cur_line -le $line_count ] ;
do  
   # NONE of the values in the variables inside this do loop are trapped here.
   filename=$(echo "$ls_output" | readline -n $cur_line)
   # Now line contains a filename from the preceeding ls command
   cur_line=cur_line+1
done

现在你已经结束了所有的子shell活动纳入整洁的小载包,可以去你的shell代码,而不必担心会被困在子shell的变量值的范围。

我写我的版本的readline在GNUC如果有人想复制,这是一个有点大,张贴在这里,但也许我们可以找到一种方法...

希望这有助于RT



文章来源: Handle special characters in bash for…in loop