因此,我尝试将其设为单个命令,而不必将数据转储到文件中,然后对文件进行 cat 并将输出通过管道传输到 wc -l。整行代码如下所示:
for file in `grep Rawdata freeze2-1.out | awk '{print $6}'`
do
ls -1 /appdata/frozen_files/$file | wc -l
done
但输出给了我每行的计数,而不是整个输出的总数。无论如何,我可以在获得所有文件的单个数字的输出的情况下完成此操作,还是必须重定向到文件并执行另一个步骤?
答案1
您正在尝试计算 freeze2-1.out 文件中字段 6 命名的目录中的文件总数,但仅限于该文件该行某处出现“Rawdata”的位置。
您最初的帖子中的主要错误只是逻辑或位置上的一个错误;你要求wc -l
计算各个行的数量里面询问整个循环提供的总行数的循环。这就是大多数现有答案正在纠正的问题。
我制作了一个示例 freeze2-1.out 文件,以便我可以“在家玩”;这是我放入的内容:
Rawdata 2 3 4 5 file1
Rawdata 2 3 4 5 file2
Rawdata 2 3 4 5 file3
我还填充了一个相对的名为“appdata/frozen_files”的目录,目录名称基于上面的字段 6。请注意,您的实际路径是绝对以 /appdata/frozen_files 开头的路径。我在 file1 中放置了 1 个文件,在 file2 中放置了 2 个文件,在 file3 中放置了 3 个文件,总共 6 个文件。
我建议的第一个改进是将grep
和结合起来awk
,因为 awk 可以进行模式匹配。罗曼·佩雷赫雷斯特他们的回答中也这样做了:
awk '/Rawdata/ { print $6 }' freeze2-1.out
示例输出为:
file1
file2
file3
我将在这里指出,由于 awk 根据空格、制表符和换行符分割字段,因此专门打印字段 6 意味着每行输出将有一个不带空格的单词。
有几种方法可以计算目录中的文件数量。使用的ls -1 | wc -l
是A方式,但在文件名嵌入换行符的特殊情况下会失败;您可以使用 手动创建这样的文件touch $'file\nname'
。由于 awk 正在读取由换行符分隔的输入行,因此我们不会在这里遇到这种特殊情况,但我想提一下。例如:
# create the file
$ touch $'file\nname'
# check the listing; looks okay so far
$ ls -1
appdata
file?name
freeze2-1.out
# count them up
$ ls -1 | wc -l
4
# woops! should be 3!
因此,我将演示另外两种方法来计算目录中的文件数量。
第一个方法使用set
内置函数获取其参数并将它们转换为以 $1、$2、$3 等命名的位置参数。
$ sum=0
$ for file in $(awk '/Rawdata/ { print $6 }' freeze2-1.out)
do
set -- "appdata/frozen_files/${file}/"*
sum=$((sum + $#))
done
$ echo "$sum"
6
这会将计数器初始化sum
为零,然后循环遍历 awk 输出中的文件名。它set
使用带引号的目录路径进行调用,后跟*
shell glob,它扩展到该目录中的所有(非隐藏)文件。这ls -1
与排除隐藏文件(以句点开头的文件)的行为相匹配。参数的数量由特殊变量 给出$#
,我们将其添加到循环中sum
,然后在最后打印它。
对于支持数组的 shell,第二种方法是将通配符文件名放入数组中,然后对数组的元素进行计数:
$ sum=0
$ for file in $(awk '/Rawdata/ { print $6 }' freeze2-1.out )
do
n=("appdata/frozen_files/${file}"/*)
sum=$((sum + ${#n[@]}))
done
$ echo "$sum"
6
答案2
将字数移至末尾;
for file in $(grep Rawdata freeze2-1.out | awk '{print $6}')
do
ls -1 /appdata/frozen_files/$file
done | wc -l
或求和;
C=0
for file in $(grep Rawdata freeze2-1.out | awk '{print $6}')
do
C=$[$C+$(ls -1 /appdata/frozen_files/$file | wc -l)]
done
echo $C;
或者也许使用 find 如果您的文件结构可以匹配模式(或正则表达式)
find /appdata/frozen_files/ -iname '*.raw' |wc -l