Пересечение двух списков в Bash
Я пытаюсь написать простой скрипт, который будет перечислять содержимое, найденное в двух списках. Чтобы упростить, давайте использовать ls в качестве примера. Представьте, что "один" и "два" являются каталогами.
один =`лс один` two=`ls two` пересечение $ один $ два
Я все еще довольно зеленый в Bash, так что не стесняйтесь исправить, как я это делаю. Мне просто нужна команда, которая распечатает все файлы в "один" и "два". Они должны существовать в обоих. Вы можете назвать это "пересечением" между "один" и "два".
6 ответов
Решение сcomm
comm
это здорово, но действительно нужно работать с отсортированным списком. И, к счастью, здесь мы используем ls
который из ls
Страница руководства Bash
Сортируйте записи по алфавиту, если ни -cftuSUX, ни --sort.
comm -12 <(ls one) <(ls two)
Альтернатива сsort
Пересечение двух списков:
sort <(ls one) <(ls two) | uniq -d
симметричная разница двух списков:
sort <(ls one) <(ls two) | uniq -u
бонус
Играть с этим;)
cd $(mktemp -d) && mkdir {one,two} && touch {one,two}/file_{1,2}{0..9} && touch two/file_3{0..9}
Использовать comm
команда:
ls one | sort > /tmp/one_list
ls two | sort > /tmp/two_list
comm -12 /tmp/one_list /tmp/two_list
"sort" на самом деле не нужен, но я всегда включаю его перед использованием "comm" на всякий случай.
Менее эффективная (чем комм) альтернатива:
cat <(ls 1 | sort -u) <(ls 2 | sort -u) | uniq -d
Присоединение является еще одним хорошим вариантом в зависимости от ввода и желаемого результата
join -j1 -a1 <(ls 1) <(ls 2)
Есть еще один вопрос Stackru "Пересечение массива в 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".