Учитывая два дерева каталогов, как определить, какие имена файлов совпадают, учитывая только имена файлов, удовлетворяющие условию? - PullRequest
0 голосов
/ 16 сентября 2018

Этот ответ говорит мне, как найти файлы с одинаковыми именами в двух каталогах в 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))

Как я могу это решить?


Я пытался это сделатьследующим образом, основываясь на этом ответе :

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 голосов
/ 16 сентября 2018

Принятый ответ работает отлично. Хотя, если кому-то нужна реализация на 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")
0 голосов
/ 16 сентября 2018

Это не проверено, но я бы попробовал что-то вроде:

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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...