AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 407252
Accepted
FaxMax
FaxMax
Asked: 2017-11-28 02:24:54 +0800 CST2017-11-28 02:24:54 +0800 CST 2017-11-28 02:24:54 +0800 CST

将字符串列表更改为小写

  • 772

我有两个文件,一个文件包含一个字符串列表。

+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 行。

text-processing
  • 3 3 个回答
  • 728 Views

3 个回答

  • Voted
  1. Best Answer
    Sundeep
    2017-11-28T03:02:17+08:002017-11-28T03:02:17+08:00

    With 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"
    


    正如 Stéphane Chazelas 所指出的,如果内容不受控制,这可能会导致代码注入f1漏洞

    • 3
  2. RomanPerekhrest
    2017-11-28T02:50:44+08:002017-11-28T02:50:44+08:00

    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"
    
    • 2
  3. Stéphane Chazelas
    2017-11-28T03:14:59+08:002017-11-28T03:14:59+08:00

    使用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) 吞入其中。我们在空格上拆分它(与is in相同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选项。

    • 2

相关问题

  • grep 从 $START 到 $END 的一组行并且在 $MIDDLE 中包含匹配项

  • 重新排列字母并比较两个单词

  • 在awk中的两行之间减去相同的列

  • 多行文件洗牌

  • 如何更改字符大小写(从小到大,反之亦然)?同时[重复]

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    JSON数组使用jq来bash变量

    • 4 个回答
  • Marko Smith

    日期可以为 GMT 时区格式化当前时间吗?[复制]

    • 2 个回答
  • Marko Smith

    bash + 通过 bash 脚本从文件中读取变量和值

    • 4 个回答
  • Marko Smith

    如何复制目录并在同一命令中重命名它?

    • 4 个回答
  • Marko Smith

    ssh 连接。X11 连接因身份验证错误而被拒绝

    • 3 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Marko Smith

    systemctl 命令在 RHEL 6 中不起作用

    • 3 个回答
  • Marko Smith

    rsync 端口 22 和 873 使用

    • 2 个回答
  • Marko Smith

    以 100% 的利用率捕捉 /dev/loop -- 没有可用空间

    • 1 个回答
  • Marko Smith

    jq 打印子对象中所有的键和值

    • 2 个回答
  • Martin Hope
    EHerman JSON数组使用jq来bash变量 2017-12-31 14:50:58 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST
  • Martin Hope
    Drux 日期可以为 GMT 时区格式化当前时间吗?[复制] 2017-12-26 11:35:07 +0800 CST
  • Martin Hope
    AllisonC 如何复制目录并在同一命令中重命名它? 2017-12-22 05:28:06 +0800 CST
  • Martin Hope
    Steve “root”用户的文件权限如何工作? 2017-12-22 02:46:01 +0800 CST
  • Martin Hope
    Bagas Sanjaya 为什么 Linux 使用 LF 作为换行符? 2017-12-20 05:48:21 +0800 CST
  • Martin Hope
    Cbhihe 将默认编辑器更改为 vim for _ sudo systemctl edit [unit-file] _ 2017-12-03 10:11:38 +0800 CST
  • Martin Hope
    showkey 如何下载软件包而不是使用 apt-get 命令安装它? 2017-12-03 02:15:02 +0800 CST
  • Martin Hope
    youxiao 为什么目录 /home、/usr、/var 等都具有相同的 inode 编号 (2)? 2017-12-02 05:33:41 +0800 CST
  • Martin Hope
    user223600 gpg —list-keys 命令在将私钥导入全新安装后输出 uid [未知] 2017-11-26 18:26:02 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve