Ändern einer Liste von Zeichenfolgen in Kleinbuchstaben

Ändern einer Liste von Zeichenfolgen in Kleinbuchstaben

Ich habe zwei Dateien, eine Datei enthält eine Liste von Zeichenfolgen.

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

und die zweite Datei (csv) enthält so etwas wie:

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

Das Ergebnis sollte sein:

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

Wie kann ich die Zeichenfolgen, die meiner Musterliste entsprechen, in Kleinbuchstaben ändern?

Meine Datei mit durch Kommas getrennten Werten hat ungefähr 30 Spalten und ungefähr 1500 Zeilen.

Antwort1

Mit GNU sedwird angenommen, dass Sie kein Metazeichen in der Liste der Zeichenfolgen haben, +ist kein Metazeichen mit Standard-BRE

$ # 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 
  • \LZeichenfolge in Kleinbuchstaben umwandeln
  • gzum Ersetzen aller Vorkommen in einer Zeile, ifür die Groß- und Kleinschreibung nicht berücksichtigende Suche


Wenn Sie nicht habenGNU 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"


Wie Stéphane Chazelas bemerkte, könnte dies zu Code-Injection-Schwachstellen führen, wenn der Inhalt f1nicht unter Kontrolle ist

Antwort2

Mit perl, vorausgesetzt, Sie möchten jeweilsWortin der ersten Datei, die in Kleinbuchstaben umgewandelt werden soll:

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

local $/ = undefmacht den Datensatztrenner für den BEGIN-Block undefiniert, so dass der eine Aufruf von <>dort die ganze erste Datei ( file1.words) ausschlürft. Wir teilen das an Leerzeichen auf ( split " "ist in perlgenauso speziell wie awk -F " "in awk) und verbinden die resultierenden Wörter mit |nach demRegex-zitiertsie und machten sie groß- und kleinschreibungsunabhängig.

Wir haben also einen riesigen regulären Ausdruck, der in etwa so aussieht, (?i:word1)|(?i:word2)|...als würden wir ihn im Rest des Codes auf jede Zeile der zweiten Datei anwenden.

Wenn es jede Saite in jeder istLinieder ersten Datei, dann lässt sich das wie folgt vereinfachen:

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

Dort öffnen wir die erste Datei auf stdin, anstatt sie als Argument zu übergeben. <STDIN>gibt eine Liste ihrer Zeilen zurück, aus der wir die Trennzeichen mit entfernen chompund |wie oben mit verknüpfen.

Wenn Sie keine Beschränkung auf ASCII-Zeichen wünschen, fügen Sie die -Mopen=localeOption hinzu.

Antwort3

AWKLösung (für Ihre aktuelle Eingabe):

Angenommen, das zweite Feld ist von Hauptinteresse und die Werte in der Suchdatei stehen in doppelten Anführungszeichen.

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"- wickeln Sie einMusterZeile mit doppelten Anführungszeichen beim Durchlaufen der Zeilen der patternsDatei

  • a[$0]- Aufnahme einesMusterZeile in Arraya

  • $2 in a{ $2=tolower($2) }- wenn der 2. Feldwert aus der Dateizeile file.csvin der Liste der Muster (d. h. Array a) enthalten ist, konvertieren Sie alle darin enthaltenen Zeichen in Kleinbuchstaben$2=tolower($2)


Die Ausgabe:

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

verwandte Informationen