使用Bash遍历目录中的特定文件find
Shellcheckdoesn't like my for
over find
在Bash中循环。使用Bash遍历目录中的特定文件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
?
第6行:空白空间在< < (find).
中做什么<
像往常一样重定向?如果是,那么重定向到do
区块意味着什么?
有人可以帮忙解析一下吗?这是迭代目录中某种类型文件的正确方法吗?
第一行:什么是''文件?
据help read
,即''
是一个参数传递给-d
参数:
-d delim continue until the first character of
DELIM is read, rather than newline
在线路六:什么空白处做< <(查找)。
这里有两个独立的操作符。有<
,标准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
循环。
<是否像往常一样重定向?如果他们是,那么重定向到阻止什么意思?
重定向进入一个循环意味着环路 从stdin
读取内部的任何命令将从重定向的输入源中读取。作为 的副作用,该循环内的所有内容都在一个子shell中运行,该子shell对变量范围有 的影响:在循环外部, 循环内设置的变量不可见。
有人可以帮忙解析一下吗?这是迭代目录中某种类型文件的正确方法吗?
为了记录在案,我通常会通过管道向find
xargs
, 虽然它的解决方案是最好的做这取决于在一定上你想做什么 延伸。在你的问题中的两个例子完全不同的事情,并不清楚你实际上试图完成 。
但例如:
find $src -maxdepth 1 -name '*.md' -print0 |
xargs -0 -iDOC wc -w DOC
这将在所有*.md
文件运行wc
。 -print0
至find
(和-0
至xargs
)允许该命令正确处理具有嵌入空白的 文件名(例如,This is my file.md
)。如果 你知道你没有任何这些,你只是做:
find $src -maxdepth 1 -name '*.md' |
xargs -iDOC wc -w DOC
一般情况下,你需要使用find
如果你想通过做一个目录树进行递归搜索(虽然有现代化的bash,你可以设置shell选项globstar
,如shellcheck建议的那样)。但在这种情况下,你已经-maxdepth 1指定的,所以你的find
命令刚刚上市的匹配模式"$src"/*.md
哪些文件。既然如此,这是更简单,使用更可靠的水珠(模式):
for f in "$src"/*.md; do
wc -w < "$f"
done >> "$path"/tmp.txt
(我还引用了所有的变量扩展,安全和移动的输出重定向所以它适用于整个)
如果您需要使用find
(因为glob不起作用),那么您应该尝试使用-exec
选项来查找,这并不需要绕过其他选项以避免在文件名中处理错误的特殊字符。例如,你可以这样做:
find "$src" -maxdepth 1 -name '*.md' -exec do wc -w {} + >> "$path"/tmp.txt
为了回答您的具体问题:
在
IFS= read -r -d '' file
,该''
是参数的-d
选项。该选项用于指定划定要读取行的字符;默认情况下使用换行符,以便read
一次读取一行。空字符串与指定NUL字符相同,如果您指定-print0
选项,则find
在每个文件名的末尾输出该字符。 (不像-exec
,-print0
不是POSIX标准,因此不能保证每find
实施工作,但实际上它是相当普遍可用。)<
和<(...)
之间的空间,以避免产生令牌<<
,这会显示一个这里的文件。相反,它指定来自进程替换(<(...)
)的重定向(<
)。
计数的话在所有降价文件,在第一个例子。第二个例子来自这个建议。谢谢你的回答! – denten