maindir/sub1/file1.txt
maindir/sub1/file2.txt
maindir/sub2/file1.txt
maindir/sub2/file2.txt
maindir/sub3/file1.txt
maindir/sub3/file2.txt
我正在尝试读取这些文本文件中的所有行,但如果可能的话,我想使用循环在父目录中搜索任何文本文件。而不是写下每个文件的绝对路径。
更新:稍后我要实现的阅读部分类似于
while read p
do
echo $p
done < file.txt
答案1
find maindir -type f -name "*.txt"
答案2
使用一个简单的循环:
shopt -s dotglob nullglob
shopt -s globstar
for pathname in maindir/**/*.txt; do
[ ! -f "$pathname" ] && continue
cat "$pathname"
done
上面的代码迭代 中该端bash
下的所有路径名。与常规文件(或常规文件的符号链接)不对应的名称将被跳过(这就是附带测试的结果)。其余的被传递到逐行输出。maindir
.txt
continue
cat
顶部设置的 shell 选项执行以下操作:
dotglob
:启用通配模式来匹配隐藏名称。nullglob
:如果不匹配,则完全删除通配模式。通常,不匹配的通配模式保持其未扩展的形式。globstar
:启用 的使用**
,其工作方式有点类似*
,但允许/
在路径名中进行匹配。换句话说,它允许“递归”匹配子目录。
您可以替换cat "$pathname"
为您需要执行的任何处理"$pathname"
。
和find
:
find maindir -type f -name '*.txt' -exec cat {} +
这与循环执行相同的操作,但有三个微小的差异:
- 它找不到常规文件的符号链接。
find
与其选项一起使用-L
以包含这些内容,例如 ,find -L maindir ...
但请注意,这也会使实用程序以符号方式遍历目录。如果当前路径名是符号链接,则find
可以使用 的GNU 实现-xtype
来代替 来-type
测试所引用事物的类型。 - 它
cat
一次调用尽可能多的找到的文件。 - 它可能以不同于循环(按字典顺序对找到的文件进行排序)的另一种(未排序)顺序呈现数据。
您可以更换
-exec cat {} +
与更通用的
-exec sh -c 'for pathname do ...; done' sh {} +
其中...
应替换为"$pathname"
您需要的任何处理。