Ответ 1
comm -12 <(ls 1) <(ls 2)
Я пытаюсь написать простой script, который отобразит содержимое, содержащееся в двух списках. Чтобы упростить, позвольте использовать ls в качестве примера. Представьте, что "один" и "два" - это каталоги.
one=`ls one` two=`ls two` intersection $one $two
Я все еще довольно зеленый в bash, поэтому не стесняйтесь исправить то, как я это делаю. Мне просто нужна команда, которая будет распечатывать все файлы в "одном" и "двух". Они должны существовать в обоих. Вы можете назвать это "пересечением" между "одним" и "двумя".
comm -12 <(ls 1) <(ls 2)
Используйте команду comm
:
ls one | sort > /tmp/one_list
ls two | sort > /tmp/two_list
comm -12 /tmp/one_list /tmp/two_list
"сортировка" на самом деле не нужна, но я всегда включаю ее, прежде чем использовать "comm" на всякий случай.
Решение с comm
comm
отлично, но нужно работать с отсортированным списком. И, к счастью, здесь мы используем ls
, который из ls
Bash man page
Сортировка записей в алфавитном порядке, если ни один из -cftuSUX или --sort.
comm -12 <(ls one) <(ls two)
Альтернатива с sort
Пересечение двух списков:
sort <(ls one) <(ls two) | uniq -d
симметричная разность двух списков:
sort <(ls one) <(ls two) | uniq -u
Bonus
Играйте с ним;)
cd $(mktemp -d) && mkdir {one,two} && touch {one,two}/file_{1,2}{0..9} && touch two/file_3{0..9}
Менее эффективная (чем комм) альтернатива:
cat <(ls 1 | sort -u) <(ls 2 | sort -u) | uniq -d
Соединение - это еще один хороший вариант в зависимости от ввода и желаемого вывода
join -j1 -a1 <(ls 1) <(ls 2)
Есть еще один вопрос о Stackoverflow "Пересечение массива в bash", который помечен как дубликат этого. Это не совсем то же самое, на мой взгляд, поскольку этот вопрос говорит о сравнении двух массивов bash, в то время как этот вопрос фокусируется на файлах bash. Однострочный ответ на другой вопрос, который теперь закрыт, выглядит следующим образом:
# List1=( 0 1 2 3 4 6 7 8 9 10 11 12)
# List2=( 1 2 3 5 6 8 9 11 )
# List3=($(comm -12 <(echo ${List1[*]}| tr " " "\n"| sort) <(echo ${List2[*]} | tr " " "\n"| sort)| sort -g))
# echo ${List3[*]}
1 2 3 6 8 9 11
Утилита comm выполняет буквенно-цифровой сортировку, тогда как "пересечение массива в bash" отвечает номерам; следовательно, использование "sort" и "sort -g".