LINUX.ORG.RU

сравнение 2х списков

 ,


0

1

Доброго дня господа.
Есть вопрос на весьма тривиальную задачку.
Есть 2 списка ссылок на файлы. Для примера:

list1:
/home/user/test
/home/user/.test
/home/user/.test_1

list2:
/home/user/dir/test
/home/user/dir/.test
/home/user/dir/.test_1
Я хочу сравнить эти два списка, а точнее проверить наличие всех файлов с списка 1 в списке 2, и получить 2 ссылки на 2 файла c 100% идентичными именами (ака /home/user/.test -> /home/user/dir/.test).
Я пошел стандартным путём.
Для каждой строки из списка 1 - искал совпадения в списке 2.
На практике:
for var in $list1
    file_compare=$(echo "$list2" | grep -w $(basename $var) | sed '1!d')
done
И столкнулся с тем, что греп даёт мне первой строкой не идеальное совпадение, а что-то другое (не всегда, но тут так).
Если творить через точный шаблон (grep -x) - нужно городить еще один for в for'e, как я это вижу (через awk, к примеру).
Но это какой-то подводный костыль с диким оверхэдом.
Как это было бы разумней сделать по-красоте?
Спасибо адекватно ответившим.

Ответ на: комментарий от Spirit_of_Stallman

Например, sed'ом вырезаешь корневые пути у списков и grep -f list1 list2

redgremlin ★★★★★
()
#!/bin/bash

LIST1=$(cat list1)
LIST2=$(cat list2)

for FULLNAME in $LIST1
do
        FILENAME=$(basename $FULLNAME)
        FILENAME2=$(grep -E "/$FILENAME$" list2)
        echo $FILENAME2
done
shell-script ★★★★★
()
Ответ на: комментарий от shell-script

Вот так работает, но костыль, конечно.

#!/bin/bash

LIST1=$(cat list1)
LIST2=$(cat list2)

for FULLNAME in $LIST1
do
        FILENAME=$(basename $FULLNAME)
        FILENAME=$(echo $FILENAME | sed -e 's/\./\\./')
        FILENAME2=$(grep -E "\/$FILENAME$" list2)
        echo $FILENAME2
done

shell-script ★★★★★
()
Ответ на: комментарий от shell-script

-E «\/$FILENAME$»

Спасибо большое.
По началу делал всё так же, кроме одной детальки, о которой просто не подумал, от чего откинул этот вариант как так же не на 100% валидный - «$», конец строки.
Еще раз спасибо.

Spirit_of_Stallman ★★★
() автор топика

Элементарно же.

Сначала отрезать общий префикс. Каждому списку сделать sort и uniq. Списки слить (sort -m). Сделать uniq -c. awk-ом выбрать все строки, у которых в первом столбце двойка — они присутствуют в обоих списках.

geekless ★★
()
Ответ на: комментарий от yu-boot

Это не одноразовая задача, и обязательное условие - баш.
ЗЫ: и да, творение гения Мацумото - тут было бы очень кстати, но не всё в жизни так просто :D

Spirit_of_Stallman ★★★
() автор топика
Ответ на: комментарий от Spirit_of_Stallman

Это grep в данном случае — танцы. А у меня — простое и элегантное (и быстрое!) решение. Ты б еще на каждую букву по отдельному процессу рожал.

geekless ★★
()
Последнее исправление: geekless (всего исправлений: 1)
Ответ на: комментарий от geekless

Окей, пойдём по пунктам:

начала отрезать общий префикс

Будь добр, укажи где было сказано что они имеют общий префикс?
Без тянучки - нет, общего префикса нету, сравниваю только файлы, о чём и написал

у которых в первом столбце двойка — они присутствуют в обоих списках

Опустим сказанное выше, сделаем вид что еще актуально:
А задачу ты так и не сумел прочесть? Мне нужно получить пару из ссылок.
Как её получить в итогах? Таки отгрепать? ;)
Ну или еще пару действий, простых инструментов не пользуем, ни в коем.

Spirit_of_Stallman ★★★
() автор топика
Ответ на: комментарий от Spirit_of_Stallman

Будь добр, укажи где было сказано что они имеют общий префикс?

/home/user/test
/home/user/.test
/home/user/.test_1

Шо я такое вижу?

geekless ★★
()
Ответ на: комментарий от geekless

Шо я такое вижу?

И? Ты видишь не существующие файлы, для примера, если верить тому, что я написал :)
Никаких указаний что это паттерны нет.

Spirit_of_Stallman ★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.