Ссылаться

Ссылаться

Фрагмент типичного tsv-файла, который я использовал

10  Interstellar    Main Theme Extended UDVtMYqUAyw
11  Journey XvG78AmBLc4
12  Jurassic Park Music & Ambience  Amazing Soundscapes and Music   PPl__iyIg6w
13  Lord of the Rings   Sound of The Shire  chLZQtCold8
14  Lord of the Rings   The Shire: Sunset at Bag End    uBmbI8dzc-M

Следующий код ищет слово lord (без учета регистра) во 2-м столбце всех tsv-файлов:

awk '$2~IGNORECASE = 1;/lord/{print}' *.tsv 

13      Lord of the Rings       Sound of The Shire      chLZQtCold8
14      Lord of the Rings       The Shire: Sunset at Bag End    uBmbI8dzc-M

Теперь я хотел передать Lordкак переменную окружения bash:

$ awk -v Pattern="Lord" '$2~Pattern{print}' *.tsv 
13      Lord of the Rings       Sound of The Shire      chLZQtCold8
14      Lord of the Rings       The Shire: Sunset at Bag End    uBmbI8dzc-M

Проблема

Как выполнить сопоставление шаблона без учета регистра?

Я попробовал следующее, но это не работает

awk -v Pattern="lord" '$2~IGNORECASE = 1;Pattern{print}' *.tsv

awk -v Pattern="lord" 'IGNORECASE = 1;$2~Pattern{print}' *.tsv

awk -v Pattern="lord" 'BEGIN {IGNORECASE = 1}  {$2~Pattern{print}}' *.tsv 

awk -v Pattern="Lord" '{IGNORECASE = 1; $2~Pattern}' *.tsv 

Ссылаться

решение1

Во-первых, я сомневаюсь, что это $2~IGNORECASE = 1;/lord/{print}работает так, как вы думаете - насколько мне известно, оно присваивает значение 1переменной IGNORECASE; сравнивает значение $2с результатом (т.е. $2 ~ 1) и по умолчанию выводит $0, если результат истинен; затем сравнивает $0без учета регистра с /lord/итакжепечатает, $0если это правда.

Если вы хотите сравнить $2без учета регистра, вы можете использовать

gawk 'BEGIN{IGNORECASE = 1} $2 ~ /lord/{print}` *.tsv

или просто

gawk 'BEGIN{IGNORECASE = 1} $2 ~ /lord/` *.tsv

Эквивалент с переменной будет таким:

gawk -v Pattern="lord" 'BEGIN{IGNORECASE = 1} $2 ~ Pattern' *.tsv

Обратите внимание, что IGNORECASEэто не стандартная функция awk — насколько мне известно, gawkее поддерживает только GNU awk ( ) — для переносимости вы можете использовать toupperили tolower, чтобы перенести входные данные в определенный регистр.

решение2

Что касается The following searches for lord (case insensitively) in 2nd column of all tsv files: awk '$2~IGNORECASE = 1;/lord/{print}' *.tsv- нет, он этого вообще не делает. Он сравнивает регулярное выражение для $2 с результатом назначения IGNORECASE значения 1, что всегда верно, и поэтому он печатает текущую строку. Затем он ищет любую строку, соответствующую регулярному выражению lordв любом месте строки, и, найдя ее, печатает строку во второй раз. Вы, вероятно, имели в виду сделать awk 'BEGIN{IGNORECASE = 1} $2~/lord/' *.tsvтак, как вы описываете.

Не используйте слово «шаблон» в этом контексте, так как оно весьма двусмысленно. Вы используете Pattern как частичное соответствие регулярному выражению, но описываете его так, как будто хотите полное соответствие строке слова. Поэтому, пожалуйста, замените «шаблон» на все 3 string-or-regexp и partial-or-full и word-or-line везде, где оно встречается в вашем вопросе, чтобы мы могли помочь вам найти правильное решение. Смотритекак-найти-текст-соответствующий-шаблонуЧтобы получить больше информации.

Вот несколько возможных решений того, что вы, возможно, пытаетесь сделать:

Частичное совпадение строки:

$ awk -v var="$var" -F'\t' 'index(tolower($2),tolower(var))' file.tsv
13  Lord of the Rings   Sound of The Shire  chLZQtCold8
14  Lord of the Rings   The Shire: Sunset at Bag End    uBmbI8dzc-M

Полное совпадение строки слова:

$ awk -v var="$var" -F'\t' 'index(" "tolower($2)" ",tolower(var))' file.tsv
13  Lord of the Rings   Sound of The Shire  chLZQtCold8
14  Lord of the Rings   The Shire: Sunset at Bag End    uBmbI8dzc-M

Полное совпадение строки:

$ awk -v var="$var" -F'\t' 'tolower($2) == tolower(var)' file.tsv
$

Частичное совпадение с регулярным выражением:

$ awk -v var="$var" -F'\t' 'tolower($2) ~ tolower(var)' file.tsv
13  Lord of the Rings   Sound of The Shire  chLZQtCold8
14  Lord of the Rings   The Shire: Sunset at Bag End    uBmbI8dzc-M

Полное совпадение с регулярным выражением:

$ awk -v var="$var" -F'\t' '(" "tolower($2)" ") ~ tolower(var)' file.tsv
13  Lord of the Rings   Sound of The Shire  chLZQtCold8
14  Lord of the Rings   The Shire: Sunset at Bag End    uBmbI8dzc-M

Полное соответствие регулярному выражению:

$ awk -v var="$var" -F'\t' 'tolower($2) ~ ("^"tolower(var)"$")' file.tsv
$

Вышеизложенное предполагает, что ваша переменная оболочки не содержит escape-последовательностей или, если содержит, вы хотите, чтобы они были расширены. Если это не так, то используйте ENVIRON[]или ARGV[]для передачи значения переменной оболочки в awk вместо -v, см.как-использовать-переменные-shell-в-скрипте-awkдля получения подробной информации.

решение3

С perl:

Поиск шаблона во втором поле файла:

perl -F"\t" -lane '$F[1] =~ /(?i)lord/ and print' input.tsv
  • -F"\t"потому что файл tsv
  • $F[1]является вторым файлом записи, поскольку поля имеют нулевую индексацию.
  • (?i)нечувствителен ли к регистру параметр в регулярном выражении
  • или модификатор iможет использоваться для обеспечения независимости от регистра, как в
perl -F"\t" -lane '$F[1] =~ /lord/i and print' input.tsv

Регулярное выражение, сопоставляющее переменную оболочки, можно выполнить exportследующим образом:

export p=lord
perl -F"\t" -lane '$F[1] =~ /(?i)$ENV{p}/ and print' input.tsv
perl -F"\t" -lane '$F[1] =~ /$ENV{p}/i and print' input.tsv

Поиск во всех .tsvфайлах папки:

perl -F"\t" -lane '$F[1] =~ /$ENV{p}/i and print' *.tsv

Если вам нужно имя файла с записями, то подойдет следующее:

perl -F"\t" -lane '$F[1] =~ /$ENV{p}/i and print $ARGV. ":" .$_' *.tsv

решение4

Если вам не нужно использоватьawkи может использовать инструмент, предназначенный для обработки табличных данных, напримерGoCSV, это проще простого.

На основе предоставленного вами образца данных я придумал несколько названий и предположил, что это «Путешествие»:

вход.tsv

ИДЕНТИФИКАТОР Альбом Отслеживать Хэш
10 Интерстеллар Основная тема расширена UDVtMYqUAyw
11 Путешествие XvG78AmBLc4
12 Музыка и атмосфера Юрского периода Удивительные звуковые ландшафты и музыка PPl__iyIg6w
13 Властелин колец Звук Шира chLZQtCold8
14 Властелин колец Шир: Закат в Бэг-Энде uBmbI8dzc-M
  1. установить переменную оболочкиpattern
  2. разделительдля преобразования TSV в CSV
  3. фильтрв столбце 2 с инвариантный к регистру --регулярное выражениеэтой переменной оболочки
  4. обезглавитьчтобы получить только совпадающие строки
  5. преобразовать обратно в TSV:
pattern='lord'
gocsv delim -i "\t" input.tsv              \
| gocsv filter -c 2 -i --regex "$pattern"  \
| gocsv behead                             \
| gocsv tsv

13      Lord of the Rings       Sound of The Shire      chLZQtCold8
14      Lord of the Rings       The Shire: Sunset at Bag End    uBmbI8dzc-M

Связанный контент