Инструменты Linux, чтобы рассматривать файлы как наборы и выполнить операции присвоения на них

Промокание поднимает интересный вопрос - поведение по умолчанию соединения дважды с той же сессией отличается в tmux. Однако, если Вы хотите присоединить дважды и иметь независимое представление окон на той сессии - запускают tmux с

tmux new-session -t <session name>

Это создаст новую сессию для Вас и присоединит окна от уже существующей сессии. Если Вы не назвали свою первую сессию, можно добавить один с 'переименовывать-сессией'.

84
15.04.2011, 02:23
12 ответов

Принимающие элементы являются строками символов кроме NUL, и новая строка (остерегайтесь, та новая строка допустима в именах файлов, хотя), можно представить набор как текстовый файл с одним элементом на строку и использовать некоторые стандартные утилиты Unix.

Членство в наборе

$ grep -Fxc 'element' set   # outputs 1 if element is in set
                            # outputs >1 if set is a multi-set
                            # outputs 0 if element is not in set

$ grep -Fxq 'element' set   # returns 0 (true)  if element is in set
                            # returns 1 (false) if element is not in set

$ awk '$0 == "element" { s=1; exit }; END { exit !s }' set
# returns 0 if element is in set, 1 otherwise.

$ awk -v e='element' '$0 == e { s=1; exit } END { exit !s }'

Пересечение набора

$ comm -12 <(sort set1) <(sort set2)  # outputs intersect of set1 and set2

$ grep -xF -f set1 set2

$ sort set1 set2 | uniq -d

$ join -t <(sort A) <(sort B)

$ awk '!done { a[$0]; next }; $0 in a' set1 done=1 set2

Равенство набора

$ cmp -s <(sort set1) <(sort set2) # returns 0 if set1 is equal to set2
                                   # returns 1 if set1 != set2

$ cmp -s <(sort -u set1) <(sort -u set2)
# collapses multi-sets into sets and does the same as previous

$ awk '{ if (!($0 in a)) c++; a[$0] }; END{ exit !(c==NR/2) }' set1 set2
# returns 0 if set1 == set2
# returns 1 if set1 != set2

$ awk '{ a[$0] }; END{ exit !(length(a)==NR/2) }' set1 set2
# same as previous, requires >= gnu awk 3.1.5

Кардинальность набора

$ wc -l < set     # outputs number of elements in set

$ awk 'END { print NR }' set

$ sed '$=' set

Тест подмножества

$ comm -23 <(sort -u subset) <(sort -u set) | grep -q '^'
# returns true iff subset is not a subset of set (has elements not in set)

$ awk '!done { a[$0]; next }; { if !($0 in a) exit 1 }' set done=1 subset
# returns 0 if subset is a subset of set
# returns 1 if subset is not a subset of set

Объединение набора

$ cat set1 set2     # outputs union of set1 and set2
                    # assumes they are disjoint

$ awk 1 set1 set2   # ditto

$ cat set1 set2 ... setn   # union over n sets

$ sort -u set1 set2  # same, but doesn't assume they are disjoint

$ sort set1 set2 | uniq

$ awk '!a[$0]++' set1 set2       # ditto without sorting

Дополнение множества

$ comm -23 <(sort set1) <(sort set2)
# outputs elements in set1 that are not in set2

$ grep -vxF -f set2 set1           # ditto

$ sort set2 set2 set1 | uniq -u    # ditto

$ awk '!done { a[$0]; next }; !($0 in a)' set2 done=1 set1

Установите симметричное различие

$ comm -3 <(sort set1) <(sort set2) | tr -d '\t'  # assumes not tab in sets
# outputs elements that are in set1 or in set2 but not both

$ sort set1 set2 | uniq -u

$ cat <(grep -vxF -f set1 set2) <(grep -vxF -f set2 set1)

$ grep -vxF -f set1 set2; grep -vxF -f set2 set1

$ awk '!done { a[$0]; next }; $0 in a { delete a[$0]; next }; 1;
       END { for (b in a) print b }' set1 done=1 set2

Степенное множество

Все возможные подмножества набора отобразили разделенное пространство, один на строку:

$ p() { [ "$#" -eq 0 ] && echo || (shift; p "$@") |
        while read r; do printf '%s %s\n%s\n' "$1" "$r" "$r"; done; }
$ p $(cat set)

(предполагает, что элементы не содержат SPC, ВКЛАДКУ (принимающий значение по умолчанию $IFS), обратная косая черта, подстановочные символы).

Установите декартово произведение

$ while IFS= read -r a; do while IFS= read -r b; do echo "$a, $b"; done < set1; done < set2

$ awk '!done { a[$0]; next }; { for (i in a) print i, $0 }' set1 done=1 set2

Непересекающийся тест набора

$ comm -12 <(sort set1) <(sort set2)  # does not output anything if disjoint

$ awk '++seen[$0] == 2 { exit 1 }' set1 set2 # returns 0 if disjoint
                                             # returns 1 if not

Тест пустого множества

$ wc -l < set            # outputs 0  if the set is empty
                         # outputs >0 if the set is not empty

$ grep -q '^' set        # returns true (0 exit status) unless set is empty

$ awk '{ exit 1 }' set   # returns true (0 exit status) if set is empty

Минимум

$ sort set | head -n 1   # outputs the minimum (lexically) element in the set

$ awk 'NR == 1 { min = $0 }; $0 < min { min = $0 }; END { print min }'
# ditto, but does numeric comparison when elements are numerical

Максимум

$ sort test | tail -n 1    # outputs the maximum element in the set

$ sort -r test | head -n 1

$ awk '$0 > max { max = $0 }; END { print max }'
# ditto, but does numeric comparison when elements are numerical

Все доступные по http://www.catonmat.net/blog/set-operations-in-unix-shell-simplified/

111
27.01.2020, 19:30
  • 1
    я думаю версия Python, намного более прост и более интуитивен. ;-) –  Keith 23.04.2011, 02:37
  • 2
    я думаю, что это - самый полный ответ. К сожалению, который управляет для выполнения или какие аргументы (коммуникация-12,-23,-13) в каждом случае не всегда интуитивно как "пересечение" или "различие". Maybe'll создают обертку вокруг них, так как я всегда использую эти вещи. –  nilton 26.04.2011, 01:08
  • 3
    я выполнил [pol@localhost inst] $ grep-xc и ДВОИЧНЫЙ УСТАНОВКОЙ 0 [pol@localhost inst] $, но я не понимаю то, что это означает. Слово "и" должно много раз происходить в файле. Что я делаю неправильно? –  Vérace 03.02.2015, 13:06
  • 4
    Пересечение Набора: sort set1 set2 | uniq -d не работает на мультимножества. Рассмотреть использование sort <(sort -u set1) <(sort -u set2) | uniq -d. –  neo 28.08.2016, 16:15

Вид. Необходимо иметь дело с сортировкой себя, но comm может использоваться, чтобы сделать это, рассматривая каждую строку как элемент множества: -12 для пересечения, -13 для различия. (И -23 дает Вам зеркально отраженное различие, то есть, set2 - set1 вместо set1 - set2.) Объединение sort -u в этой установке.

11
27.01.2020, 19:30
  • 1
    Действительно, коммуникация, кажется, делает большую часть материала. Хотя аргументы очень неинтуитивны.Спасибо! –  nilton 26.04.2011, 01:09

Я не знаю об определенном инструменте, но можно использовать Python, и его класс набора и операторы, для записи небольшого сценария, чтобы сделать это.

Для exampe:

Python> s1 = set(os.listdir("/bin"))
Python> s2 = set(os.listdir("/usr/bin"))
Python> s1 & s2

set(['awk',
     'basename',
     'chroot', ...
7
27.01.2020, 19:30
  • 1
    Да, хороший ответ. Почему использование awk, если Python доступен? –  guettli 17.11.2015, 11:23
  • 2
    Вы забыли: Python> import os –  James Bowery 23.10.2016, 22:48

Если Вы рассматриваете файл как ряд строк, и файлы отсортированы, существует comm.

Если Вы рассматриваете файл как (много) набор строк, и строки не отсортированы, grep может сделать различие и пересечение (оно достигает разности множеств и пересечения, но не уважает счет для мультимножеств). Объединение справедливо cat.

grep -xF -f small large >intersection
grep -vxF -f small large >difference
cat small large >union
3
27.01.2020, 19:30

Файловая система рассматривает имена файлов (целые имена файлов, включая пути) как уникальные.

Операции?

Можно скопировать файлы в a/и b/к пустому каталогу c/, для получения нового, набора объединения.

С тестами файла как -e name и циклы или находят, можно проверить на файлы, существующие в двух или больше каталогах, для получения пересечения или различия.

0
27.01.2020, 19:30
  • 1
    я означал рассматривать содержание файлов как элементы набора (скажем, один элемент на строку), и самих файлов как наборы. –  nilton 26.04.2011, 01:04

Я сделал утилиту Python, которая может сделать мудрое строкой объединение, пересечение, различие и продукт нескольких файлов. Это назвало SetOp, можно найти его на PyPI (здесь). Синтаксис похож на это:

$ setop -i file1 file2 file3  # intersection
$ setop -d file1 file2 file3  # difference
2
27.01.2020, 19:30

Я записал немного инструмента, чтобы сделать это, которое было довольно полезно для меня в различных местах. UI не отполирован, и я не уверен в рабочих характеристиках для очень больших файлов (так как он читает целый список в память), но "он работает на меня". Программа в https://github.com/nibrahim/lines. Это находится в Python. Можно получить его использование pip install lines.

Это в настоящее время поддерживает объединение, пересечение, различие и симметричное различие двух файлов. Каждую строку входного файла рассматривают как элемент набора.

Это также начинает две дополнительных операции. Один из отжимает пустые строки в файле и втором (который был очень полезен для меня), должен просмотреть файл и разделить его на наборы подобных строк. Мне было нужно это для поиска файлов в списке, который не соответствовал общему шаблону.

Я приветствовал бы обратную связь.

1
27.01.2020, 19:30

Лучший ответ Здесь: Отложение (выделенный инструмент)

Я написал программу, называемую SEPDown, которая выполняет заданные операции с CLI.

Он может выполнять установленные операции, написав определение, аналогичное тому, что вы бы написали в Makefile:

someUnion: "file-1.txt" \/ "file-2.txt"
someIntersection: "file-1.txt" /\ "file-2.txt"
someDifference: someUnion - someIntersection

его довольно круто, и вы должны проверить это. Я лично не рекомендую использовать Ad-HOC команды, которые не были созданы для работы для выполнения заданных операций. Это не будет хорошо работать, когда вам действительно нужно делать много настроек, или если у вас есть какие-либо заданные операции, которые зависят друг от друга. Отказ Не только это, но orddown позволяет вам писать набор операций, которые зависят от других настроек!

Во всяком случае, я думаю, что это довольно круто, и вы должны полностью проверить это.

0
27.01.2020, 19:30

Образец шаблона для нескольких файлов (в данном случае пересечение):

eval `perl -le 'print "cat ",join(" | grep -xF -f- ", @ARGV)' t*`

Расширяется до:

cat t1 | grep -xF -f- t2 | grep -xF -f- t3

Тестовые файлы:

seq 0 20 | tee t1; seq 0 2 20 | tee t2; seq 0 3 20 | tee t3

Вывод:

0
6
12
18
0
27.01.2020, 19:30

Con matrices zsh(zshlas matrices pueden contener cualquier secuencia arbitraria de bytes, incluso 0 ).

(también tenga en cuenta que puede hacer typeset -U arraypara garantizar que sus elementos sean únicos ).

establecer membresía

if ((${array[(Ie)$element]})); then
  echo '$element is in $array'
fi

(usando el indicador de subíndice de matriz I, para obtener el índice de la última aparición de $elementen la matriz (o 0 si no se encuentra ). Quitare(para exact )para que $elementse tome como patrón)

if ((n = ${(M)#array:#$element})); then
  echo "\$element is found $n times in \$array'
fi

${array:#pattern}es una variación de ksh ${var#pattern}que elimina los elementos que coinciden con el patrón en lugar de simplemente eliminar la parte principal que coincide con el patrón. El(M)(para emparejado)invierte el significado y elimina todos menos los elementos emparejados (use $~elementpara que se tome como un patrón ).

establecer intersección

common=("${(@)set1:*set2}")

${set1:*set2}realiza la intersección del arreglo, pero se necesita la sintaxis "${(@)...}"para preservar los elementos vacíos.

establecer igualdad

[[ ${(j: :)${(q)array1}} = ${(j: :)${(q)array2}} ]]

Comprueba si las matrices son idénticas (y en el mismo orden ). El indicador de expansión del parámetro qcita los elementos (para evitar problemas con cosas como a=(1 "2 3")frente a b=("1 2" 3)), y (j: :)los une con un espacio antes de hacer una comparación de cadenas.

Para comprobar que tienen los mismos elementos, independientemente del orden, utilice la bandera opara ordenarlos. Consulte también el indicador u(único )para eliminar duplicados.

[[ ${(j: :)${(qo)array1}} = ${(j: :)${(qo)array2}} ]]

establecer cardinalidad

n=$#array

prueba de subconjunto

if ((${#array1:*array2} == ${#array2})); then
  echo '$array2 is included in $array1'
fi

sindicato

union=("$array1[@]" "$array2[@]")

(consulte typeset -Uarriba o el indicador de expansión de parámetros upara tomar el caso de duplicados ). Nuevamente, si la cadena vacía no es uno de los valores posibles, puede simplificar a:

union=($array1 $array2)

complemento

complement=("${(@)array1:|array2}")

para los elementos de $array1que no están en $array2.

mínimo/máximo (comparación léxica)

min=${${(o)array}[1]} max=${${(o)array}[-1]}

mínimo/máximo (comparación de enteros decimales)

min=${${(no)array}[1]} max=${${(no)array}[-1]}
1
27.01.2020, 19:30

Миниатюрный консольный инструмент «setop» теперь доступен в Debian Stretch и в Ubuntu с версии 16.10. Вы можете получить его через sudo apt install setop

Вот несколько примеров. Наборы, над которыми нужно работать, задаются как разные входные файлы :. setop input # is equal to "sort input --unique" setop file1 file2 --union # option --union is default and can be omitted setop file1 file2 file3 --intersection # more than two inputs are allowed setop file1 - --symmetric-difference # ndash stands for standard input setop file1 -d file2 # all elements contained in 1 but not 2

Логические запросы возвращают только EXIT_SUCCESSв случае истинности и EXIT_FAILURE, а также сообщение в противном случае. Таким образом, setop можно использовать в оболочке. setop inputfile --contains "value" # is element value contained in input? setop A.txt B.txt --equal C.txt # union of A and B equal to C? setop bigfile --subset smallfile # analogous --superset setop -i file1 file2 --is-empty # intersection of 1 and 2 empty (disjoint)?

Также можно точно описать, как должны анализироваться входные потоки, фактически с помощью регулярных выражений:

  • setop input.txt --input-separator "[[:space:]-]"означает, что пробел (i. е.\v\t\n\r\fили пробел )или минус интерпретируется как разделитель между элементами (по умолчанию новая строка, т.е. е. каждая строка входного файла является одним элементом)
  • setop input.txt --input-element "[A-Za-z]+"означает, что элементами являются только слова, состоящие из латинских символов, все остальные символы считаются разделителями между элементами

Кроме того, вы можете

  • --countвсе элементы выходного множества,
  • --trimвсе входные элементы (i. е. удалить все нежелательные предшествующие и последующие символы, такие как пробел, запятая и т. д. ),
  • считать пустые элементы действительными через --include-empty,
  • --ignore-case,
  • установить --output-separatorмежду элементами выходного потока (по умолчанию \n),
  • и так далее.

См. man setopили github.com/phisigma/setop для получения дополнительной информации.

10
27.01.2020, 19:30

Для ответа на этот вопрос я написал на Go командный инструмент. Исходный код здесь на GitHub .

Вы можете использовать homebrewдля установки на macOS:

brew install suzaku/homebrew-rose/rose

Использование просто:

  • rose and file1 file2для пересечения.
  • rose or file1 file2для союза.
  • rose sub file1 file2для вычитания.
1
16.09.2021, 06:40

Теги

Похожие вопросы