【问题标题】:Using shell scripts to remove all commas except for the first on each line使用 shell 脚本删除除每行第一个逗号之外的所有逗号
【发布时间】:2020-11-18 01:02:43
【问题描述】:

我有一个文本文件,它由所有以数字代码开头的行组成,后跟一个或多个单词、一个逗号,然后是一个用逗号分隔的单词列表。除了第一个逗号之外,我需要删除每一行中的所有逗号。例如:

1.2.3 Example question, a, question, that, is, hopefully, not, too, rudimentary

which should be changed to

1.2.3 Example question, a question that is hopefully not too rudimentary

我尝试使用 sed 和 shell 脚本来解决这个问题,我可以弄清楚如何删除每行的第一个逗号 (1) 以及如何删除所有逗号 (2),但不知道如何只删除逗号每行第一个逗号后

(1)

while read -r line
do
 echo "${line/,/}"
done <"filename.txt" > newfile.txt
mv newfile.txt filename.txt

(2)

sed 's/,//g'  filename.txt  > newfile.txt

【问题讨论】:

    标签: bash shell sed


    【解决方案1】:

    您需要捕获第一个逗号,然后删除其他逗号。一种选择是将第一个逗号更改为其他未使用的字符(例如 Control-A),然后删除剩余的逗号,最后用逗号替换替换字符:

    sed -e $'s/,/\001/; s/,//g; s/\001/,/'
    

    (使用 Bash ANSI C quoting\001 映射到 Control-A)。

    另一种机制使用sed 的标签和分支,如Wiktor Stribiżewanswer 所示。

    【讨论】:

    • 由于换行符总是在将当前行转移到 sed 中的模式空间之前被删除,它通常(除非由程序员引入)永远不会在模式空间中。因此对于 GNU sed sed 's/,/\n/;s///g;s/\n/,/' file 是一个安全的习惯用法。
    【解决方案2】:

    如果使用 GNU sed,您可以在 seds/// 命令的标志中指定一个数字以及 g 以指示从哪个匹配开始替换:

    $ sed 's/,//2g' <<<'1.2.3 Example question, a, question, that, is, hopefully, not, too, rudimentary'
    1.2.3 Example question, a question that is hopefully not too rudimentary
    

    它的manual 说:

    注意:POSIX 标准没有指定当您混合使用 gNUMBER 修饰符时应该发生什么,并且目前在 sed 实现中没有广泛同意的含义。对于 GNU sed,交互定义为:忽略NUMBERth 之前的匹配,然后匹配并替换NUMBERth 之后的所有匹配。

    因此,如果您使用不同的sed,您的里程可能会有所不同。 (例如,OpenBSD 和 NetBSD seds 会引发错误)。

    【讨论】:

      【解决方案3】:

      你可以使用

      sed ':a; s/^\([^,]*,[^,]*\),/\1/;ta' filename.txt > newfile.txt
      

      详情

      • :a - 设置 a 标签
      • s/^\([^,]*,[^,]*\),/\1/ - 在字符串的开头找到 0+ 个非逗号,一个逗号和 0+ 个非逗号,将此子字符串捕获到第 1 组中,然后仅匹配 , 并将匹配替换为组的内容1(删除非第一个逗号)
      • ta - 成功替换后,跳转回a 标签位置。

      查看online sed demo

      s='1.2.3 Example question, a, question, that, is, hopefully, not, too, rudimentary'
      sed ':a; s/^\([^,]*,[^,]*\),/\1/;ta' <<< "$s"
      # => 1.2.3 Example question, a question that is hopefully not too rudimentary
      

      【讨论】:

        【解决方案4】:
        awk 'NF>1 {$1=$1","} 1' FS=, OFS= filename.txt
        
        sed ':a;s/,//2;t a' filename.txt
        
        sed 's/,/\
        /;s/,//g;y/\n/,/' filename.txt
        

        【讨论】:

          【解决方案5】:

          这可能对你有用(GNU sed):

          sed 's/,/&\n/;h;s/,//g;H;g;s/\n.*\n//' file
          

          在第一个逗号后添加换行符。

          将当前行复制到保留空间。

          删除当前行中的所有逗号。

          将当前行附加到保留空间。

          将当前行换成保留空间。

          删除引入的换行符之间的所有内容。

          【讨论】:

            猜你喜欢
            • 2012-12-03
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-12-03
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多