【问题标题】:lowercase and remove punctuation from a csv小写并从 csv 中删除标点符号
【发布时间】:2023-02-10 02:43:53
【问题描述】:

我有一个巨大的文件 (6gb),它是一个 csv,行看起来像这样:

"87687","institute Polytechnic, Brazil"
"342424","university of India, India"
"24343","univefrsity columbia, Bogata, Colombia"

我想删除所有标点符号并降低第二列屈服的大小写:

"87687","institutepolytechnicbrazil"
"342424","universityofindiaindia"
"24343","univefrsitycolumbiabogatacolombia"

在终端上执行此操作的最有效方法是什么?

试过:

cat TEXTFILE | tr -d '[:punct:]' > OUTFILE

问题:结果不是小写的,而且 tr 似乎作用于两列,而不仅仅是第二列。

【问题讨论】:

  • 请添加到您的问题(无评论):您搜索了什么,找到了什么?你尝试了什么,它是如何失败的?
  • @Cyrus 请不要在这里耍小聪明。这是一个简单的问题。
  • 您应该向我们展示您尝试过的内容,或者至少,搜索过的内容...
  • 完成伙计们......字面意思并不重要,但无论如何。

标签: bash awk sed grep


【解决方案1】:

使用sed

$ sed -E ':a;s/([^,]*,)([^ ,]*)[ ,]([[:alpha:]]+)/L/;ta' input_file
"87687","institutepolytechnicbrazil"
"342424","universityofindiaindia"
"24343","univefrsitycolumbiabogatacolombia

【讨论】:

  • 哦,你在哪里要求sed只在第二列工作?
  • @AJW sed 正在使用L 处理第二个和第三个反向引用,降低它们的大小写。
  • 对不起@Hatless back reference 在这里是什么意思?抱歉,如果这听起来很愚蠢
  • 不过,这仅在第一个字段中没有逗号时才有效。
  • @AJW 看看这个可以更好地理解反向引用gnu.org/software/sed/manual/html_node/…
【解决方案2】:

我建议使用这个 awk 解决方案,它应该适用于任何版本的 awk

awk 'BEGIN{FS=OFS="",""} {
   gsub(/[^[:alnum:]"]+/, "", $2); $2 = tolower($2)} 1' file

"87687","institutepolytechnicbrazil"
"342424","universityofindiaindia"
"24343","univefrsitycolumbiabogatacolombia"

细节:

  • 我们在BEGIN块中制作","输入和输出字段分隔符
  • gsub(/[^[:alnum:]"]+/, "", $2):去除除"之外的所有非字母数字字符
  • $2 = tolower($2):第二列小写

【讨论】:

    【解决方案3】:

    另一种sed方法-

    $: sed -E 's/ +//g; s/([^"]),//g; s/"([^"]*)"/"L"/g' file
    "87687","institutepolytechnicbrazil"
    "342424","universityofindiaindia"
    "24343","univefrsitycolumbiabogatacolombia"
    

    【讨论】:

      【解决方案4】:

      在 Perl 中使用 real CSV parser

      perl -CSD -Mutf8 -MText::CSV -lne '
          BEGIN{
              our $csv = Text::CSV->new({ sep_char => "," });
          };
          $csv->parse($_) or die "parse error";
          print join ",", map { s/(?:s+|,)//g; lc($_) } $csv->fields();
      ' file.csv
      

      输出

      87687,institutepolytechnicbrazil
      342424,universityofindiaindia
      24343,univefrsitycolumbiabogatacolombia
      

      【讨论】:

        【解决方案5】:

        一个GNU awkgensub())的想法:

        awk '
        BEGIN { FS=OFS=""" }
              { $4=gensub(/[^[:alnum:]]/,"","g",tolower($4)) }
        1'
        

        这会产生:

        "87687","institutepolytechnicbrazil"
        "342424","universityofindiaindia"
        "24343","univefrsitycolumbiabogatacolombia"
        

        【讨论】:

          【解决方案6】:

          这是使用 xsv 和进程替换的方法:

          paste -d, 
              <(xsv select 1 infile.csv) 
              <(xsv select 2 infile.csv | sed 's/[[:blank:][:punct:]]*//g;s/.*/L&/')
          

          sed 命令首先删除所有空格和标点符号,然后将整个匹配项小写。

          这在第一个字段包含空格和逗号时也有效,并在需要时保留引号。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2023-01-03
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-09-07
            相关资源
            最近更新 更多