Referir

Referir

Um trecho de um arquivo tsv típico que usei

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

As seguintes pesquisas por senhor (sem distinção entre maiúsculas e minúsculas) na 2ª coluna de todos os arquivos 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

Agora, eu queria passar Lordcomo uma variável de ambiente 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

Problema

Como fazer a correspondência de maiúsculas e minúsculas de forma insensível?

Eu tentei o seguinte, mas não funciona

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 

Referir

Responder1

Em primeiro lugar, duvido que $2~IGNORECASE = 1;/lord/{print}funcione da maneira que você pensa - AFAIK atribui valor 1à variável IGNORECASE; compara o valor de $2com o resultado (ou seja $2 ~ 1, ) e por padrão imprime $0se o resultado for verdadeiro; em seguida, compara $0sem distinção entre maiúsculas e minúsculas /lord/etambémimprime $0se isso for verdade.

Se sua intenção é comparar $2sem distinção entre maiúsculas e minúsculas, você pode usar

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

ou apenas

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

O equivalente com uma variável seria

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

Observe que IGNORECASEnão é um recurso padrão do awk - até onde eu sei, apenas o GNU awk( gawk) o suporta - para portabilidade você pode usar toupperou tolowerpara obter a entrada em um caso específico.

Responder2

Em relação a The following searches for lord (case insensitively) in 2nd column of all tsv files: awk '$2~IGNORECASE = 1;/lord/{print}' *.tsv- não, não faz nada disso. Ele faz uma comparação regexp de $2 com o resultado da atribuição de IGNORECASE a 1, que é sempre verdadeiro, e assim imprime a linha atual. Em seguida, ele procura qualquer string que corresponda ao regexp lordem qualquer lugar da linha e imprime a linha uma segunda vez. Você provavelmente pretendia fazer awk 'BEGIN{IGNORECASE = 1} $2~/lord/' *.tsvo que descreve.

Não use a palavra “padrão” neste contexto, pois é altamente ambígua. Você está usando Pattern como uma correspondência parcial de regexp, mas descrevendo-o como se quisesse uma correspondência de string de palavra completa. Portanto, substitua "padrão" por todos os 3 string-ou-regexp e parcial ou completo e palavra ou linha em todos os lugares em que ocorrer em sua pergunta para que possamos ajudá-lo a encontrar a solução certa. Vercomo-faço-para-encontrar-o-texto-que-corresponde-a-um-padrãoPara maiores informações.

Aqui estão algumas soluções possíveis para o que você pode estar tentando fazer:

Correspondência parcial de strings:

$ 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

Correspondência de string de palavra completa:

$ 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

Correspondência de string de linha completa:

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

Correspondência parcial de regexp:

$ 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

Correspondência de regexp de palavra completa:

$ 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

Correspondência de regexp de linha completa:

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

O texto acima pressupõe que sua variável shell não contém sequências de escape ou, se desejar, você deseja que elas sejam expandidas. Se não for esse o caso, use ENVIRON[]ou ARGV[]para passar o valor da variável shell para awk em vez de -v, consultecomo faço para usar variáveis ​​​​shell em um script awkpara detalhes.

Responder3

Com perl:

Procurando um padrão no segundo campo do arquivo:

perl -F"\t" -lane '$F[1] =~ /(?i)lord/ and print' input.tsv
  • -F"\t"é porque o arquivo é tsv
  • $F[1]é o segundo arquivo de registro porque os campos são indexados em zero.
  • (?i)é uma opção que não diferencia maiúsculas de minúsculas em regex
  • ou modificador ipode ser usado para insensibilidade a maiúsculas e minúsculas, como em
perl -F"\t" -lane '$F[1] =~ /lord/i and print' input.tsv

regex correspondente a uma variável shell pode ser feito exportcomo em

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

Pesquisando em todos .tsvos arquivos de uma pasta:

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

Se você quiser um nome de arquivo com registros, o seguinte seria o suficiente:

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

Responder4

Se você não precisa usarestranhoe pode usar uma ferramenta dedicada ao processamento de dados tabulares, comoGoCSV, isso é muito fácil.

Começando com a amostra de dados que você forneceu, inventei alguns nomes e adivinhei "Journey":

entrada.tsv

EU IA Álbum Acompanhar Cerquilha
10 Interestelar Tema principal estendido UDVtMYqUAyw
11 Jornada XvG78AmBLc4
12 Música e ambiente do Jurassic Park Paisagens sonoras e músicas incríveis PPl__iyIg6w
13 Senhor dos Anéis Som do Condado chLZQtCold8
14 Senhor dos Anéis The Shire: Pôr do sol em Bolsão uBmbI8dzc-M
  1. definir a variável shellpattern
  2. deslimpara converter o TSV para CSV
  3. filtrona coluna 2 com o-eu invariante de caso --regexdaquela variável shell
  4. decapitarpara obter apenas as linhas correspondentes
  5. converter de volta para 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

informação relacionada