如何在文本文件中的引号之间替换单个或两个空格

如何在文本文件中的引号之间替换单个或两个空格

我有一个 CSV 文件,其中一些字段被引用,但引号内的条目由双空格或单空格分隔。我需要将它们替换为逗号。

示例行:

This is okay,"ABC DEF GHI",123,"This is not okay",remove,spaces,within,quotes

以及它应该是什么样子:

This is okay,"ABC,DEF,GHI",123,"This,is,not,okay",remove,spaces,within,quotes

答案1

perl -pe 's/".*?"/do{$a = $&; $a =~ s: +:,:g; $a}/ge;'

本质上,这只是全局正则表达式的替换s/regex/replacement/g。正则表达式是,它匹配以下一个".*?"开头和结尾的每个子字符串。棘手的部分是:""

  • 替换的不是字符串,而是计算的表达式。 (这就是e后面修饰符的意思g。)
  • 计算的表达式又是一个全局正则表达式替换s:regex:replacement:g,它用逗号替换任何非空的空格序列。 (我们不能使用与外部替换相同的分隔符,因此我们使用:代替/。)
  • 为了执行内部正则表达式替换,我们必须将外部替换的匹配子字符串分配$&给其他变量$a,然后执行内部替换$a,最后打印$a

使用足够新的 perl 版本,可以避免对辅助变量的赋值。使用r修饰符,可以直接在匹配子字符串的副本上执行内部替换$&(感谢 Stéphane Chazelas):

perl -pe 's/".*?"/$&=~s: +:,:gr/ge;'

答案2

考虑这个暴力的 awk 解决方案:

awk -F, -v OFS=, '
  {
    for(i=1;i<=NF;i++)
        if ($i ~ /^".*"$/)
                gsub(" +", ",", $i)
    print $0
  }'

它告诉 awk 用逗号分割记录 - 请注意,如果您的任何字段包含逗号,这将会中断! -- 并使用 OFS 告诉 print 语句用逗号重新组合字段。循环for遍历该行的每个字段,如果该字段^以双引号开头、包含任何字符.*$以双引号结尾,则全局$i用逗号替换该字段中任意数量的空格。循环遍历字段后,打印整个记录 ( $0)。

答案3

使用 GNU awk

gawk -v RS=\" '
  NR % 2 == 0{gsub(/ +/, ",")}
  {ORS = RT; print}'

也就是说,记录分隔符"仅在偶数记录上替换字符和空格。

RT是 GNU 特定的部分。

与 GNU 相同sed

tr '\n"' '"\n' | sed -E '2~2s/ +/,/g' | tr '"\n' '\n"'

更便携:

tr '\n"' '"\n' | sed 'n;s/  */,/g' | tr '"\n' '\n"'

可以与其他一些seds 一起使用,但如果输入的最后一个字符不是 则可能会遇到问题"

相关内容