通过Bash循环读取空分隔的字符串

Mat*_*hew 42 bash delimiter null-character

我想迭代一个文件列表,而不关心文件名可能包含哪些字符,所以我使用一个由空字符分隔的列表.代码将更好地解释事情.

# Set IFS to the null character to hopefully change the for..in
# delimiter from the space character (sadly does not appear to work).
IFS=$'\0'

# Get null delimited list of files
filelist="`find /some/path -type f -print0`"

# Iterate through list of files
for file in $filelist ; do
    # Arbitrary operations on $file here
done
Run Code Online (Sandbox Code Playgroud)

从文件读取时,以下代码有效,但我需要从包含文本的变量中读取.

while read -d $'\0' line ; do
    # Code here
done < /path/to/inputfile
Run Code Online (Sandbox Code Playgroud)

Sie*_*geX 69

在bash中,您可以使用here-string

while IFS= read -r -d '' line ; do
    # Code here
done <<<"$var"
Run Code Online (Sandbox Code Playgroud)

请注意,您应该内联IFS=并使用,-d ''但请确保'd'和第一个单引号之间有空格.另外,添加-r标志以忽略转义.

此外,这不是您的问题的一部分,但我可能会建议您在使用时更好的方式来执行您的脚本find; 它使用流程替换.

while IFS= read -r -d '' file; do
    # Arbitrary operations on "$file" here
done < <(find /some/path -type f -print0)
Run Code Online (Sandbox Code Playgroud)

  • @thisirs通过将`IFS`设置为空字符串,将保留前导和尾随空白字符. (7认同)
  • 这不是将 IFS 设置为空字符串。它是 [取消设置 IFS,导致它使用默认值 ($' \t\n')](https://mywiki.wooledge.org/IFS)。 (3认同)
  • 设置了 -d 标志后,IFS 的用途是什么? (2认同)
  • 完全同意@joanpau。我不知道这些东西在2011年是如何工作的,但是在2016年使用bash4时,此方法不起作用。如果在while循环之前分配`var = $(find。-print0)`,您可以轻松地验证是否失败。进程替换确实有效,但变量无效。即使您像`var = $(echo -e“ some \ 0text”)这样动态地构建了变量,也无法将“ some”与“ text”分开。对于变量,您需要使用以下技巧:http://stackoverflow.com/questions/6570531/assign-string- contains-null-character-0-to-a-variable-in-bash (2认同)
  • @jeremysprofile 实际上,`IFS=` 正在*禁用*分词。它*不*像`unset IFS`那样将IFS设置回其默认值。 (2认同)

小智 6

将它们通过管道传输到xargs -0

files="$( find ./ -iname 'file*' -print0 | xargs -0 )"

xargs 手册

-0, --null
    Input items are terminated by a null character instead of
    by whitespace, and the quotes and backslash are not
    special (every character is taken literally).
Run Code Online (Sandbox Code Playgroud)