给定两个目录树,仅考虑满足条件的文件名,如何查找相同的文件名?

时间:2018-09-16 00:48:48

标签: linux bash shell ubuntu terminal

This answer告诉我如何在bash的两个目录中查找具有相同文件名的文件:

diff -srq dir1/ dir2/ | grep identical

现在,我想考虑满足条件的文件。如果我使用ls E*,我将获得以E开头的文件。我想使用上述命令执行相同的操作:给我dir1/dir2/中不同的文件名,但请考虑只有那些以E开头的人。

我尝试了以下操作:

diff -srq dir1/E* dir2/E* | grep identical

但是它不起作用,我得到了以下输出:

  

diff:额外操作数'/ home / pal / konkoly / c6 / elesbe3 / 1 / EPIC_212291374-   c06-k2sc.dat.flag.spline'diff:尝试使用'diff --help'了解更多信息   信息。

(({/home/pal/konkoly/c6/elesbe3/1/EPIC_212291374- c06-k2sc.dat.flag.spline是所谓的dir1中的文件,但是EPIC_212291374- c06-k2sc.dat.flag.spline不在所谓的dir2中))

我该如何解决?


我尝试根据this answer通过以下方式进行操作:

DIR1=$(ls dir1)
DIR2=$(ls dir2)

for i in $DIR1; do
    for j in $DIR2; do
        if [[ $i == $j ]]; then
            echo "$i == $j"
        fi
    done
done

它的工作原理与上面相同,但是如果我写DIR1=$(ls path1/E*)DIR2=$(ls path2/E*)却没有,我没有输出。

2 个答案:

答案 0 :(得分:2)

这是未经测试的,但我会尝试:

comm -12 <(cd dir1 && ls E*) <(cd dir2 && ls E*)

基本思路:

  • dir1中生成满足我们条件的文件名列表。可以使用ls E*完成此操作,因为我们只处理平面文件列表。对于子目录和递归,我们将改用find(例如find . -name 'E*' -type f)。

  • 按规范顺序放置文件名(例如,通过对文件名进行排序)。我们不必在这里做任何事情,因为无论如何E*都会按排序顺序扩展。使用find,我们可能必须先将输出通过管道传输到sort

  • dir2做同样的事情。

  • 仅两个列表共有的输出行,可以使用comm -12完成。

    comm期望在命令行中传递两个文件名,因此我们使用<( ... ) bash功能生成一个子进程并将其输出连接到命名管道。然后可以将管道的名称指定为comm

答案 1 :(得分:0)

可接受的答案很好。尽管如果有人需要python实现,这也可以:

import glob

dir1withpath=glob.glob("path/to/dir1/E*")
dir2withpath=glob.glob("path/to/dir2/E*")

dir1=[]
for index,each in enumerate(dir1withpath):
    dir1list=dir1withpath[index].split("/")
    dir1.append(dir1list[-1])

dir2=[]
for index,each in enumerate(dir2withpath):
    dir2list=dir2withpath[index].split("/")
    dir2.append(dir2list[-1])

for each1 in dir1:
    for each2 in dir2:
        if each1 == each2:
            print(each1 + "is in both directories")