Cambiar una lista de cadenas a minúsculas

Cambiar una lista de cadenas a minúsculas

Tengo dos archivos, un archivo contiene una lista de cadenas.

+stringa +Dog +Cat
+cat +Tux +elephant

y el segundo archivo (csv) contiene algo como:

"123456 Abc","+Stringx +123","something"
"23456 dEf","+cat +Tux +elephant","Other something"
"34524 xyz","+stringa +Dog +Cat","third something"

el resultado debería ser:

"123456 Abc","+Stringx +123","something"
"23456 dEf","+cat +tux +elephant","Other something"
"34524 xyz","+stringa +dog +cat","third something"

¿Cómo puedo cambiar las cadenas que coinciden con mi lista de patrones a minúsculas?

Mi archivo de valores separados por comas tiene aproximadamente 30 columnas y aproximadamente 1500 filas.

Respuesta1

Con GNU sed, se supone que no tiene ningún metacarácter en la lista de cadenas, +no es un metacarácter con BRE predeterminado

$ # create substitute command for each line
$ sed 's/.*/s|"&"|\\L\&|gi/' f1
s|"+stringa +Dog +Cat"|\L&|gi
s|"+cat +Tux +elephant"|\L&|gi

$ # pass those commands as sed script
$ sed -f <(sed 's/.*/s|"&"|\\L\&|gi/' f1) ip.csv
"123456 Abc","+Stringx +123","something"
"23456 dEf","+cat +tux +elephant","Other something"
"34524 xyz","+stringa +dog +cat","third something"

$ # or save them in a file and use
$ sed 's/.*/s|"&"|\\L\&|gi/' f1 > f2
$ sed -f f2 ip.csv 
  • \Lpara convertir cadena a minúsculas
  • gpara reemplazar todas las apariciones en una línea, ipara coincidencias que no distinguen entre mayúsculas y minúsculas


Si no tienesGNU sed

$ # \Q to quote metacharacters
$ # but will have issues if you have \ or $ or @
$ sed 's/.*/s|\\Q"&"|\\L$\&|gi;/' f1
s|\Q"+stringa +Dog +Cat"|\L$&|gi;
s|\Q"+cat +Tux +elephant"|\L$&|gi;

$ perl -p <(sed 's/.*/s|\\Q"&"|\\L$\&|gi;/' f1) ip.csv 
"123456 Abc","+Stringx +123","something"
"23456 dEf","+cat +tux +elephant","Other something"
"34524 xyz","+stringa +dog +cat","third something"


Como señaló Stéphane Chazelas, esto podría provocar vulnerabilidades de inyección de código si el contenido f1no está bajo control.

Respuesta2

Conperl , suponiendo que quieras cada unopalabraen el primer archivo que se pondrá en minúsculas:

perl -pe '
 BEGIN {local $/ = undef; $regex = join "|", map qr{\Q$_\E}i, split " ", <>}
 s/$regex/\L$&/g' file1.words file2.csv

local $/ = undefhace que el separador de registros para el bloque BEGIN sea indefinido, de modo que la única invocación de <>allí absorba todo el primer archivo ( file1.words). Lo dividimos en espacios en blanco ( split " "es especial en perlde la misma manera que awk -F " "en awk) y unimos las palabras resultantes con| después de habercitado con expresiones regularesy los hizo sin distinción entre mayúsculas y minúsculas.

Entonces tenemos una expresión regular enorme que es algo así como (?i:word1)|(?i:word2)|...la que aplicamos en cada línea del segundo archivo en el resto del código.

Si es cada cadena en cadalíneadel primer archivo, entonces eso se puede simplificar a:

perl -pe '
 BEGIN {chomp (@strings = <STDIN>); $regex = join "|", map qr{\Q$_\E}i, @strings}
 s/$regex/\L$&/g' < file1.strings file2.csv

Allí, abrimos el primer archivo en stdin en lugar de pasarlo como argumento. <STDIN>devuelve una lista de sus líneas de las cuales eliminamos los delimitadores con chompy unimos con |como se indicó anteriormente.

Si no desea que se limite a caracteres ASCII, agregue la -Mopen=localeopción.

Respuesta3

AWKsolución (para su entrada actual):

Suponiendo que el segundo campo es de interés principal y los valores en el archivo de búsqueda están entre comillas dobles.

awk 'NR==FNR{ $0="\042"$0"\042"; a[$0]; next }
     $2 in a{ $2=tolower($2) }1' patterns FS=',' OFS=',' file.csv
  • $0="\042"$0"\042"- envolver unpatrónlínea con comillas dobles mientras se itera a través de las líneas del patternsarchivo

  • a[$0]- capturar unpatrónlínea en matriza

  • $2 in a{ $2=tolower($2) }- si el valor del segundo campo de la línea del file.csvarchivo está en la lista de patrones (es decir, matriz a), convierta todos los caracteres que contiene a minúsculas$2=tolower($2)


La salida:

"123456 Abc","+Stringx +123","something"
"23456 dEf","+cat +tux +elephant","Other something"
"34524 xyz","+stringa +dog +cat","third something"

información relacionada