使用find . -print0似乎是获取bash中文件列表的唯一安全方法,因为文件名可能包含空格,换行符,引号等.
但是,我很难让find的输出在bash或其他命令行实用程序中有用.我设法使用输出的唯一方法是将它传递给perl,并将perl的IFS更改为null:
find . -print0 | perl -e '$/="\0"; @files=<>; print $#files;'
Run Code Online (Sandbox Code Playgroud)
此示例打印找到的文件数,避免文件名中的换行符损坏计数的危险,如下所示:
find . | wc -l
Run Code Online (Sandbox Code Playgroud)
由于大多数命令行程序不支持空分隔输入,我认为最好的方法是捕获find . -print0bash数组中的输出,就像我在上面的perl片段中所做的那样,然后继续执行任务,无论它是什么是.
我怎样才能做到这一点?
这不起作用:
find . -print0 | ( IFS=$'\0' ; array=( $( cat ) ) ; echo ${#array[@]} )
Run Code Online (Sandbox Code Playgroud)
一个更普遍的问题可能是:如何用bash中的文件列表做有用的事情?
在尝试通过使用NULL字符作为分隔符来正确处理文件//foldernames列表(请参阅我的其他问题)时,我偶然发现了Bash的一个奇怪的行为,我不明白:
将包含一个或多个NULL字符的字符串分配给变量时,将丢失/忽略/不存储NULL字符.
例如,
echo -ne "n\0m\0k" | od -c # -> 0000000 n \0 m \0 k
Run Code Online (Sandbox Code Playgroud)
但:
VAR1=`echo -ne "n\0m\0k"`
echo -ne "$VAR1" | od -c # -> 0000000 n m k
Run Code Online (Sandbox Code Playgroud)
这意味着我需要将该字符串写入文件(例如,在/ tmp中),如果不希望或不可行直接管道,则从那里读回.
在Z shell(zsh)中执行这些脚本时,在两种情况下都会保留包含\ 0的字符串,但遗憾的是我不能假设在运行我的脚本的系统中存在zsh而Bash应该是.
如何在不丢失任何(元)字符的情况下有效地存储或处理包含\ 0字符的字符串?
我想知道我是否可以使用十六进制值作为Unix sort实用程序的分隔符.基本上我想做的事情如下:
sort -t '\x00' <input
Run Code Online (Sandbox Code Playgroud)
但如果我按照上面的方式进行,它就不起作用.