將字串列表更改為小寫

將字串列表更改為小寫

我有兩個文件,一個文件包含字串列表。

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

第二個檔案 (csv) 包含類似以下內容的內容:

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

結果應該是:

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

如何將與我的模式列表匹配的字串更改為小寫?

我的逗號分隔值檔案大約有 30 列和大約 1500 行。

答案1

使用GNU sed, 假設字串清單中沒有任何元字符,+不是預設 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將字串轉換為小寫
  • g用於替換行中所有出現的情況,i用於不區分大小寫的匹配


如果你沒有GNU 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"


f1正如 Stéphane Chazelas 所指出的,如果內容不受控制, 這可能會導致程式碼注入漏洞

答案2

perl,假設您想要每個單字在第一個要轉換為小寫的檔案中:

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

local $/ = undef使 BEGIN 區塊的記錄分隔符號未定義,以便對那裡的一次調用,將<>整個第一個檔案 ( )file1.words吞入其中split " "perlawk -F " "awk|吞入擁有以後正規表示式引用它們並使它們不區分大小寫。

因此,我們有一個巨大的正規表示式,類似於(?i:word1)|(?i:word2)|...我們在程式碼的其餘部分中應用到第二個檔案的每一行的東西。

如果是每個字串中的每個第一個文件的,那麼可以簡化為:

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

在那裡,我們在標準輸入上打開第一個文件,而不是將其作為參數傳遞。<STDIN>返回其行的列表,我們從中刪除分隔符號chomp, 並按上面的方式連接|

如果您不希望限制為 ASCII 字符,請新增該-Mopen=locale選項。

答案3

AWK解決方案(針對您目前的輸入):

假設第二個欄位是主要關注點,並且搜尋文件中的值用雙引號引起來。

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"- 包裹一個圖案patterns迭代文件行時使用雙引號的行

  • a[$0]- 捕獲一個圖案行入數組a

  • $2 in a{ $2=tolower($2) }- 如果檔案行的第二個欄位值file.csv位於模式清單中(即陣列a) - 將其中的所有字元轉換為小寫$2=tolower($2)


輸出:

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

相關內容