Друкуйте неперевершені шаблони, використовуючи греп з візерунками з файлу


15

шаблони.txt:

"BananaOpinion"
"ExitWarning"
"SomeMessage"
"Help"
"Introduction"
"MessageToUser"

Strings.xml

<string name="Introduction">One day there was an apple that went to the market.</string>
<string name="BananaOpinion">Bananas are great!</string>
<string name="MessageToUser">We would like to give you apples, bananas and tomatoes.</string>

Очікуваний вихід:

"ExitWarning"
"SomeMessage"
"Help" 

Як надрукувати ті терміни, у patterns.txtяких їх немає Strings.xml? Я можу надрукувати відповідні / незрівняні рядки в Strings.xml, але як я друкую незрівняні візерунки ? Я використовую ggrep (GNU grep) версії 2.21, але я відкритий для інших інструментів. Вибачте, якщо це дублікат іншого питання, якого я не зміг знайти.

Відповіді:


25

Ви можете використовувати grep -oдля друку лише відповідні частини та використовувати результат як візерунки на секунду grep -vу вихідному patterns.txtфайлі:

grep -oFf patterns.txt Strings.xml | grep -vFf - patterns.txt

Хоча в цьому конкретному випадку ви також можете використовувати join+ sort:

join -t\" -v1 -j2 -o 1.1 1.2 1.3 <(sort -t\" -k2 patterns.txt) <(sort -t\" -k2 strings.xml)

це досить елегантно .. розумно!
XXL

Якщо у вас є кілька вхідних файлів (наприклад, Strings1.xmlта Strings2.xml), вам також знадобиться -hпрапор на першому грепі.
jayhendren

@jayhendren - так, але не всі grepпідтримують цей варіант. Якщо у вас є кілька вхідних файлів, я не бачу, чому ви не могли просто catїх усі і передавати результат grep.
don_crissti

5

Найкращий підхід - це, мабуть, те, що запропонував @don_crissti, ось ось варіант на ту саму тему:

$ grep -vf <(grep -Po 'name=\K.+?"' Strings.xml) patterns.txt
"ExitWarning"
"SomeMessage"
"Help"

Це в основному є зворотним підходом @ don_crissti. Він використовує греп з сумісними регулярними виразами Perl ( -P) і -oперемикач, щоб друкувати лише сумісну частину рядка. Потім регекс шукає name=і відкидає його ( \K), а потім шукає одного або декількох символів до першого "( .+?"). Це призводить до переліку шаблонів, присутніх у String.txtфайлі, які потім передаються як вхід до зворотного grep ( grep -v) з використанням підстановки процесу ( <(command)).


2

Я б скористався cut, мабуть. Тобто, якщо, як виявляється, ви знаєте, де очікувати цитований рядок, який ви шукаєте.

Якщо я:

{   cut  -sd\" -f2 |
    grep -vFf- pat
}   <<\IN
#   <string name="Introduction">One day there was an apple that went to the market.</string>
#   <string name="BananaOpinion">Bananas are great!</string>
#   <string name="MessageToUser">We would like to give you apples, bananas and tomatoes.</string>
IN

... після збереження моєї власної копії вашого прикладу patterns.txtу patта запуску вищевказаної команди результат:

"ExitWarning"
"SomeMessage"
"Help"

cutдрукує для викреслення лише другого усуненого поля з "подвійною -dцитатами -fдля кожного рядка введення, що відповідає роздільникам, і -sзбільшує всі інші.

Що cutнасправді друкує, grepце:

Introduction
BananaOpinion
MessageToUser

grepшукає в іменованому файлі операнд для рядків, які -vне відповідають -Fзмішаним рядкам у його -іллі малюнка stdin -f.

Якщо ви можете розраховувати на друге "поле з обмеженими розмірами як на відповідне, то це, безумовно, буде оптимізація в grep -Pрежимі erl, просто зіставляючи -Fзмішані рядки і лише невеликі їх частини, тому cutщо це важкий підйом - і це робить це швидко .


1
for p in $(cat patterns.txt); do if ! grep $p strings.xml &>/dev/null; then echo $p; fi; done

це легко зрозуміти, але є час простою нерестування декількох греп-процесів, по одному для кожного рядка в шаблонах.txt.


0

інший спосіб - помістити pattern.txt і Strings.xml в один список і знайти унікальні рядки

cat patterns.txt Strings.xml | grep -oFf patterns.txt | sort | uniq -u

пояснення:

cat patterns.txt Strings.xmlвводить все в один список. grep -oFf patterns.txtприбирає сміття на кожному рядку. sortроз’яснення. сортувати всі рядки. uniq -uдрукує лише унікальні лінії.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.