Referirse

Referirse

Un fragmento de un archivo tsv típico que he usado

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

Lo siguiente busca señor (sin distinguir entre mayúsculas y minúsculas) en la segunda columna de todos los archivos 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

Ahora quería pasar Lordcomo variable de entorno de 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

¿Cómo hacer la coincidencia del patrón entre mayúsculas y minúsculas sin distinguir entre mayúsculas y minúsculas?

Intenté lo siguiente pero no 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 

Referirse

Respuesta1

En primer lugar, dudo que $2~IGNORECASE = 1;/lord/{print}funcione como crees: AFAIK asigna valor 1a la variable IGNORECASE; compara el valor de $2con el resultado (es decir $2 ~ 1) y, de forma predeterminada, imprime $0si el resultado es verdadero; luego compara $0sin distinguir entre mayúsculas y minúsculas /lord/ytambiénimprime $0si eso es cierto.

Si su intención es comparar $2sin distinguir entre mayúsculas y minúsculas, puede utilizar

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

o solo

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

El equivalente con una variable sería

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

Tenga en cuenta que IGNORECASEno es una característica estándar de awk; hasta donde yo sé, solo GNU awk ( gawk) la admite; puede usarla para portabilidad touppero tolowerpara obtener la entrada en un caso específico.

Respuesta2

Respecto a The following searches for lord (case insensitively) in 2nd column of all tsv files: awk '$2~IGNORECASE = 1;/lord/{print}' *.tsv... no, no hace eso en absoluto. Hace una comparación de expresiones regulares de $2 con el resultado de asignar IGNORECASE a 1, que siempre es cierto, por lo que imprime la línea actual. Luego busca cualquier cadena que coincida con la expresión regular lorden cualquier lugar de la línea y encuentra que imprime la línea por segunda vez. Probablemente quisiste hacerlo, awk 'BEGIN{IGNORECASE = 1} $2~/lord/' *.tsvya que eso haría lo que describe.

No utilice la palabra "patrón" en este contexto, ya que es muy ambigua. Estás utilizando Pattern como una coincidencia parcial de expresiones regulares, pero lo estás describiendo como si quisieras una coincidencia de cadena de palabras completa. Por lo tanto, reemplace "patrón" con los 3 de cadena o expresión regular y parcial o completo y palabra o línea en todos los lugares donde aparece en su pregunta para que podamos ayudarlo a encontrar la solución correcta. Ver¿cómo-encuentro-el-texto-que-coincide-con-un-patrón?para más información.

Aquí hay algunas posibles soluciones para lo que puede estar intentando hacer:

Coincidencia parcial de cadenas:

$ 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

Coincidencia de cadena de palabra 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

Coincidencia de cadena de línea completa:

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

Coincidencia parcial de expresiones regulares:

$ 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

Coincidencia de expresiones regulares de palabra 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

Coincidencia de expresiones regulares de línea completa:

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

Lo anterior supone que su variable de shell no contiene secuencias de escape o si las desea expandir. Si ese no es el caso, utilice ENVIRON[]o ARGV[]para pasar el valor de la variable de shell a awk en lugar de -v, consulte¿Cómo-uso-las-variables-de-shell-en-un-script-awk?para detalles.

Respuesta3

Con perl:

Buscando un patrón en el segundo campo del archivo:

perl -F"\t" -lane '$F[1] =~ /(?i)lord/ and print' input.tsv
  • -F"\t"es porque el archivo es tsv
  • $F[1]Es el segundo archivo de registro porque los campos están indexados a cero.
  • (?i)es una opción que no distingue entre mayúsculas y minúsculas en expresiones regulares
  • o ise puede utilizar un modificador para no distinguir entre mayúsculas y minúsculas como en
perl -F"\t" -lane '$F[1] =~ /lord/i and print' input.tsv

La expresión regular que coincide con una variable de Shell se puede hacer exportcomo en

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

Buscando en todos .tsvlos archivos de una carpeta:

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

Si desea un nombre de archivo con registros, lo siguiente sería suficiente:

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

Respuesta4

Si no tienes que usarawky puede utilizar una herramienta dedicada al procesamiento de datos tabulares, comoIrCSV, esto es muy fácil.

A partir de la muestra de datos que proporcionaste, inventé algunos nombres y adiviné "Viaje":

entrada.tsv

IDENTIFICACIÓN Álbum Pista Picadillo
10 Interestelar Tema principal ampliado UDVtMYqUAyw
11 Viaje XvG78AmBLc4
12 Parque Jurásico Música y ambiente Increíbles paisajes sonoros y música PPl__iyIg6w
13 señor de los Anillos Sonido de la comarca chLZQtCold8
14 señor de los Anillos La Comarca: Atardecer en Bolsón Cerrado uBmbI8dzc-M
  1. establecer la variable de shellpattern
  2. delimpara convertir el TSV a CSV
  3. filtraren la columna 2 con el-i invariante de caso --expresión regularde esa variable de shell
  4. decapitarpara obtener solo las filas coincidentes
  5. convertir de nuevo a 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

información relacionada