Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 如何在每个目录中找到文件名数最高的文件?_Linux_Bash - Fatal编程技术网

Linux 如何在每个目录中找到文件名数最高的文件?

Linux 如何在每个目录中找到文件名数最高的文件?,linux,bash,Linux,Bash,我有一个这样的文件结构 ./501.res/1.bin ./503.res/1.bin ./503.res/2.bin ./504.res/1.bin 我想在每个目录中找到.bin文件的文件路径,这些目录的文件名数最高。所以我想要的结果是 ./501.res/1.bin ./503.res/2.bin ./504.res/1.bin 一个文件可以拥有的最大数字是9 问题 在BASH中如何实现这一点 我已经找到了。| grep bin | sort我想出了这样的办法: 美元中的目录的(find

我有一个这样的文件结构

./501.res/1.bin
./503.res/1.bin
./503.res/2.bin
./504.res/1.bin
我想在每个目录中找到
.bin
文件的文件路径,这些目录的文件名数最高。所以我想要的结果是

./501.res/1.bin
./503.res/2.bin
./504.res/1.bin
一个文件可以拥有的最大数字是9

问题

在BASH中如何实现这一点


我已经找到了。| grep bin | sort

我想出了这样的办法:

美元中的目录的
(find.-mindepth 1-类型d|sort);做
文件=$(ls“$dir”| sort | tail-n1);
[-n“$file”]&(echo“$dir/$file”);
完成
也许它可以更简单

测试:

find . -type d -name '*.res' | while read dir; do
    find "$dir" -maxdepth 1 | sort -n | tail -n 1
done

使用
awk
怎么样?您可以非常简单地获得第一个事件:

[ghoti@pc ~]$ cat data1
./501.res/1.bin
./503.res/1.bin
./503.res/2.bin
./504.res/1.bin
[ghoti@pc ~]$ awk 'BEGIN{FS="."} a[$2] {next} {a[$2]=1} 1' data1
./501.res/1.bin
./503.res/1.bin
./504.res/1.bin
[ghoti@pc ~]$ 
要获取最后一个引用,您可以通过以下几种管道:

[ghoti@pc ~]$ sort -r data1 | awk 'BEGIN{FS="."} a[$2] {next} {a[$2]=1} 1' | sort
./501.res/1.bin
./503.res/2.bin
./504.res/1.bin
[ghoti@pc ~]$ 
考虑到您正在使用“查找”和“grep”,您可能可以这样做:

find . -name \*.bin -type f -print | sort -r | awk 'BEGIN{FS="."} a[$2] {next} {a[$2]=1} 1' | sort
这是如何工作的?

find
命令有许多有用的选项,包括按glob选择文件、选择文件类型等。您已经知道它的输出,这将成为
sort-r
的输入

首先,我们对输入数据进行反向排序(
sort-r
)。这确保在任何目录中,编号最高的文件将首先显示。这个结果被输入awk。FS是字段分隔符,它将
$2
转换为“/501”、““/502”等内容。Awk脚本具有
条件{action}
形式的部分,这些部分会针对每一行输入进行计算。如果缺少条件,则操作将在每一行上运行。如果“1”为条件且没有任何操作,则打印该行。所以这个脚本被分解如下:

  • a[$2]{next}
    -如果存在下标为$2(即“/501”)的数组
    a
    ,请跳到下一行。否则
  • {a[$2]=1}
    -将数组的下标$2设置为1,以便将来第一个条件的计算结果为true,然后
  • 1
    -打印该行
此awk脚本的输出将是您想要的数据,但顺序相反。最后的
排序
会按您期望的顺序重新排序

现在。。。这需要很多管道,当您要求sort同时处理数百万行输入时,它可能会有点消耗资源。这个解决方案对于少量文件来说已经足够了,但是如果您处理的是大量的输入,请告诉我们,我可以提出一个一体化的awk解决方案(这将需要60秒以上的时间来编写)

更新

根据Dennis的sage建议,我上面包含的awk脚本可以通过将其从

BEGIN{FS="."} a[$2] {next} {a[$2]=1} 1


虽然这在功能上是相同的,但优点是您只需定义数组成员,而不是为它们赋值,这可能会节省内存或cpu,具体取决于您的awk实现。无论如何,它更干净。

如果从find中调用shell是一个选项,请尝试以下操作

  find * -type d -exec sh -c "echo -n './'; ls -1 {}/*.bin | sort -n -r | head -n 1" \;

Globs保证按词汇顺序展开

for dir in ./*/
do
    files=($dir/*)           # create an array
    echo "${files[@]: -1}"   # access its last member
done
这是一条班轮

find . -mindepth 1 -type d | sort | sed -e "s/.*/ls & | sort | tail -n 1 | xargs -I{} echo &\/{}/" | bash

我认为您应该使用sort-n,因为编号可能会高于9。@b保留-OP声明“一个文件可以拥有的最高编号是9。”啊,对不起。未能注意到:)最好在{next}中使用
$2测试数组中是否存在元素。这样做并不能简单地通过引用来创建新的数组元素。这就是前几天我们讨论这个问题时我想说的。顺便说一句,如果你以那种方式使用
,你可以用
{a[$2]}
代替
{a[$2]=1}
,但两者都可以。@DennisWilliamson,啊,现在我明白你前几天得到了什么。非常感谢您的指点。:)修好了。找到-maxdepth 1现在正确显示路径。谢谢
find . -mindepth 1 -type d | sort | sed -e "s/.*/ls & | sort | tail -n 1 | xargs -I{} echo &\/{}/" | bash