![Ссылаться](https://rvso.com/image/192228/%D0%A1%D1%81%D1%8B%D0%BB%D0%B0%D1%82%D1%8C%D1%81%D1%8F.png)
Фрагмент типичного 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 |
- установить переменную оболочки
pattern
- разделительдля преобразования TSV в CSV
- фильтрв столбце 2 с-я инвариантный к регистру --регулярное выражениеэтой переменной оболочки
- обезглавитьчтобы получить только совпадающие строки
- преобразовать обратно в 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