Shellcheck doesn't like for
超过find
循环。
for f in $(find $src -maxdepth 1 -name '*.md'); do wc -w < "$f" >> $path/tmp.txt; done
它建议:
1 while IFS= read -r -d '' file
2 do
3 let count++
4 echo "Playing file no. $count"
5 play "$file"
6 done < <(find mydir -mtime -7 -name '*.mp3' -print0)
7 echo "Played $count files"
我理解其中的大部分内容,但有些事情仍然不清楚。
第一行:什么是'' file
?
第六行: < < (find).
空白空间的作用<
是否像往常一样重定向?如果是,那么重定向到do
块是什么意思?
有人可以帮忙解析一下吗?这是在目录中迭代某种文件的正确方法吗?
答案 0 :(得分:1)
第一行:什么是&#39;&#39;文件?
根据help read
,''
是-d
参数的参数:
-d delim continue until the first character of
DELIM is read, rather than newline
第六行:空白空间做什么&lt; &LT; (找到)。
那里有两个独立的运营商。有<
,标准I / O重定向运算符,后跟<(...)
构造,它是一个执行进程替换的特定于bash的构造:
Process Substitution
Process substitution is supported on systems that
support named pipes (FIFOs) or the /dev/fd method of naming
open files. It takes the form of <(list) or >(list). The
process list is run with its input or output connected
to a FIFO or some file in /dev/fd...
所以这就是将find
命令的输出发送到do
循环。
是&lt;像往常一样重定向?如果是,那么重定向到do block意味着什么?
重定向到循环意味着该循环内的任何命令
从stdin
读取的内容将从重定向的输入源中读取。作为一个
副作用,该循环内的所有内容都在子shell中运行,其中包含
关于变量范围的含义:变量设置在变量范围内
在循环之外,循环不可见。
有人可以帮忙解析一下吗?这是在目录中迭代某种文件的正确方法吗?
为了记录,我通常会通过管道find
到xargs
来执行此操作,
虽然哪种解决方案最好取决于某种程度上的延伸
你正试图这样做。你问题中的两个例子完全可以
不同的事情,并不清楚你实际上在想什么
完成。
但是例如:
find $src -maxdepth 1 -name '*.md' -print0 |
xargs -0 -iDOC wc -w DOC
这将在所有wc
个文件上运行*.md
。 -print0
到find
(以及-0
到xargs
)允许此命令正确处理
具有嵌入空格的文件名(例如,This is my file.md
)。如果
你知道你没有任何这些,你只是这样做:
find $src -maxdepth 1 -name '*.md' |
xargs -iDOC wc -w DOC
答案 1 :(得分:1)
通常,如果要通过目录树进行递归搜索,则需要使用find
(尽管使用现代bash,您可以设置shell选项globstar
,如shellcheck所示)。但在这种情况下,您已指定-maxdepth 1,因此您的find
命令只列出与模式"$src"/*.md
匹配的文件。在这种情况下,使用glob(模式)更简单,更可靠:
for f in "$src"/*.md; do
wc -w < "$f"
done >> "$path"/tmp.txt
(为了安全起见,我还引用了所有变量扩展,并移动了输出重定向,因此它适用于整个for循环,效率稍高。)
如果你需要使用find
(因为一个glob不起作用),那么你应该尝试使用-exec
选项来查找,这不需要摆弄其他选项避免文件名中错误处理的特殊字符。例如,您可以这样做:
find "$src" -maxdepth 1 -name '*.md' -exec do wc -w {} + >> "$path"/tmp.txt
回答您的具体问题:
在IFS= read -r -d '' file
中,''
是-d
选项的参数。该选项用于指定分隔要读取的行的字符;默认情况下,使用换行符,以便read
一次读取一行。空字符串与指定NUL字符相同,如果指定find
选项,则-print0
在每个文件名末尾输出。 (与-exec
不同,-print0
不是Posix标准,因此无法保证与每个find
实现一起使用,但实际上它通常可用。)
<
和<(...)
之间的空格是为了避免创建令牌<<
,这表示此处为文档。相反,它指定了流程替换(<
)的重定向(<(...)
)。