3 回答
TA贡献1816条经验 获得超4个赞
Greg的BashFAQ无耻地偷走了:
unset a iwhile IFS= read -r -d $'\0' file; do a[i++]="$file" # or however you want to process each filedone < <(find /tmp -type f -print0)
请注意,此处使用的重定向构造(cmd1 < <(cmd2)
)与更常用的管道(cmd2 | cmd1
)相似但不完全相同- 如果命令是shell内置的(例如while
),管道版本在子shell中执行它们,以及它们设置的任何变量(例如阵列a
)在退出时丢失。 cmd1 < <(cmd2)
只在子shell中运行cmd2,因此数组将超过其构造。警告:这种重定向形式仅在bash中可用,在sh仿真模式下甚至不是bash; 你必须用你的脚本开始#!/bin/bash
。
此外,因为文件处理步骤(在这种情况下,只是a[i++]="$file"
,但你可能想在循环中直接做一些更好的事情)将其输入重定向,它不能使用任何可能从stdin读取的命令。为了避免这种限制,我倾向于使用:
unset a iwhile IFS= read -r -u3 -d $'\0' file; do a[i++]="$file" # or however you want to process each filedone 3< <(find /tmp -type f -print0)
...通过单元3传递文件列表,而不是stdin。
TA贡献1836条经验 获得超5个赞
也许你正在寻找xargs:
find . -print0 | xargs -r0 do_something_useful
选项-L 1对你也很有用,这使得xargs exec do_something_useful只有1个文件参数。
TA贡献1836条经验 获得超13个赞
主要问题是,分隔符NUL(\ 0)在这里没用,因为不可能为IFS分配NUL值。因此,作为优秀的程序员,我们需要注意的是,我们程序的输入是它能够处理的。
首先,我们创建一个小程序,为我们完成这一部分:
#!/bin/bashprintf "%s" "$@" | base64
...并将其命名为base64str(不要忘记chmod + x)
其次,我们现在可以使用一个简单而直接的for循环:
for i in `find -type f -exec base64str '{}' \;`do file="`echo -n "$i" | base64 -d`" # do something with filedone
所以诀窍是,base64-string没有任何迹象会导致bash出现问题 - 当然xxd或类似的东西也可以完成这项工作。
添加回答
举报