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 sed
wird 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
\L
Zeichenfolge in Kleinbuchstaben umwandelng
zum Ersetzen aller Vorkommen in einer Zeile,i
fü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 f1
nicht 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 $/ = undef
macht 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 perl
genauso 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 chomp
und |
wie oben mit verknüpfen.
Wenn Sie keine Beschränkung auf ASCII-Zeichen wünschen, fügen Sie die -Mopen=locale
Option hinzu.
Antwort3
AWK
Lö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 derpatterns
Dateia[$0]
- Aufnahme einesMusterZeile in Arraya
$2 in a{ $2=tolower($2) }
- wenn der 2. Feldwert aus der Dateizeilefile.csv
in der Liste der Muster (d. h. Arraya
) 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"