grep -Zlr "\<THE_WORD\>" * | xargs -0 wc -l
Опции для grep:
-Z
- завершать напечатанные имена файлов нулевым/нулевым байтом для их разделения (помогает при странных именах или именах с пробелами) -l
- перечислять имена файлов, а не строки, которые соответствуют -r
- рекурсивно -i
- игнорировать регистр (необязательно, но возможно полезно для поиска ВСЕХ вариантов) А в кавычках, вокруг THE_WORD
, я использовал "разделители слов" (\<
и \>
), которые предотвращают нахождение "HI" в "WHICH". Полезно, это.
Передайте список имен файлов, содержащих "THE_WORD" с нулевым разделителем в xargs
, сообщив ему, что он ожидает разделители нулевых байт (-0
), выполните wc
(word-count), показывая количество строк (-l
)
EDIT:
Чтобы ответить на ваш вопрос в комментариях, попробуйте этот вариант: (Я провел исследование!)
grep -oi "\<THE_WORD\>" /dev/null * | sort | uniq -c
И объяснение:
-o
говорит выводить КАЖДОЕ вхождение в строку, так что если у вас есть "blah blah blah THE_WORD blah THE_WORD blah blah blah blah", он выведет ДВА раза для этой строки, без этого флага grep вывел бы только ОДИН раз для этой строки. -i
совпадают варианты верхнего и нижнего регистра (т.е. The_Word, the_word, etc)\<
должно быть началом слова, таким образом 'HI' НЕ найдено в 'WHICH'. /dev/null
фиктивное имя файла, чтобы заставить grep ВСЕГДА выводить имена файлов, даже если вы ищете только один файл. Это можно заставить, используя опцию -H
для grep, но я нахожу этот способ таким же простым и более описательным, поскольку -H
можно оценить как "малоизвестную магию"
передайте все это в sort (который, uh.... сортирует...)
передайте отсортированный список в uniq, с -c
для подсчета каждого вхождения в отсортированный список
И таадаа!!!
Пример:
File example.c contains:
(*H)->segments=realloc((*H)->segments,sizeof(segment_t*)*((*H)->segment_count+1));
xenon-lornix:~/projects/emma> grep -oi "\<H\>" /dev/null *.c | sort | uniq -c
3 example.c:H
Таким образом возвращается список из count (3), where (example.c), и what (H)!!! Вуаля!!! Урааааа!!!
Еще один, с тем же содержимым файла:
xenon-lornix:~/projects/emma> grep -oi "\<segments\>" /dev/null example.c | sort | uniq -c
2 aa.c:segments
Здесь видно, что он нашел оба сегмента, но не засчитал сегмент. Ключи \<
и \>
заставляют сопоставлять только целые слова. THE_WORD123
не НЕ соответствует _THE_WORD_, разрыв слова происходит на неалфавитно-цифровых символах. К СВЕДЕНИЮ.
Предполагая, что вы используете виртуальные машины на одном хосте, а не на нескольких хостах, самый простой способ создать сеть между виртуальными машинами QEMU и другими виртуальными машинами (или реальными хостами )— использовать ответвительные устройства вместо многоадресной рассылки., затем соедините крановые устройства и добавьте к мосту свои интерфейсы контейнера Docker (или что угодно ).
Кстати, синтаксис и описание сети в приведенной вами ссылке устарели и на каком-то этапе исчезнут. В частности, исчезнет концепция вланов QEMU. В текущем синтаксисе используйте что-то вроде
-netdev tap,ifname=qemu0
, а затем (как root)
ip link add br_qemu type bridge
ip link set br_qemu up
ip link set qemu0 master br_qemu
ip link set qemu1 master br_qemu
и т. д. Если вы создаете мост перед запуском виртуальных машин, вы также можете использовать -netdev bridge,br=br_qemu
, чтобы заставить QEMU добавить к мосту интерфейсы ответвлений.
Если вам особенно нужна многоадресная рассылка, потому что ваши виртуальные машины работают на разных физических хостах, это будет сложнее. Первым шагом было бы выяснить формат, в котором QEMU отправляет пакеты (это не необработанный пакет, но я не смотрел дальше ), а вторым — написать прокси, который присоединяется к группе многоадресной рассылки, и пересылает между этой группой и интерфейсом крана.
В качестве альтернативы (, но менее эффективно ), вы можете запустить выделенную виртуальную машину QEMU с двумя сетевыми картами, одной многоадресной рассылкой и одной ответвительной, которая настроена только на пересылку между ними.
Еще лучшей альтернативой было бы реализовать связь между различными физическими хостами по-другому (туннель, VLAN через физическую LAN (настоящие VLAN 801.q, а не QEMU )), и придерживаться крановые интерфейсы.
Редактировать
Чтобы добавить VLAN в вашу локальную сеть, скажем eth0
на хосте, просто выполните
ip link add link eth0 name eth0.5 type vlan id 5
, где 5
— выбранный вами тег VLAN. Далее добавляем этот интерфейс в мост
ip link set eth0.5 master br_qemu
и вы можете идти. Вы можете поместить эти две команды в сценарий, который вы используете для запуска виртуальных машин. В качестве альтернативы, поместите эквивалент этого в/etc/network/interfaces
(google или прочитайте справочную страницу для деталей ). Да, это требует небольшой настройки хоста.
Редактировать
Хорошо, я посмотрел формат многоадресных пакетов, отправляемых QEMU, и это всего лишь кадр Ethernet. Таким образом, вы можете сделать что-то вроде
socat UDP4-DATAGRAM:230.0.0.1:1234,sourceport=1234,ip-add-membership=230.0.0.1:10.0.0.2 TUN:10.2.3.1/24,tun-type=tap,iff-no-pi,iff-up
на хосте с контейнером докеров, где 10.0.0.2
— допустимый IP-адрес хоста по отношению к группе многоадресной рассылки, например. IP-адрес eth0
. Это даст вам интерфейсtap
(уровня 2 ), где вы сможете отправлять пакеты Ethernet и получать их от группы многоадресной рассылки. Теперь вам нужно только соединить/направить их в контейнер Docker.
Вместо socat
вы также можете написать собственную короткую программу на C и т. д., если хотите и считаете, что это более эффективно.