【问题标题】:Split a string with a delimiter and leave the first column使用分隔符拆分字符串并保留第一列
【发布时间】:2016-12-19 14:46:38
【问题描述】:

我有以下结构:

column1,column2
value1,string1;string2;string3;string4
value2,string11;string22

我想修改该结构并创建一个具有以下格式的新文件:

column1,column2
value1,string1
value1,string2
value1,string3
value1,string4
value2,string11
value2,string22

【问题讨论】:

  • 你几乎肯定想使用 awk 而不是 sed。

标签: bash sed split


【解决方案1】:

这个 awk 单行代码应该会有所帮助:

awk -F"[;,]" 'NR==1{print;next}{for(i=2;i<=NF;i++)print $1","$i}' file

【讨论】:

  • 以上对我不起作用(出于某种原因......)。相反,这可以正常工作:echo "value1,string1;string2;string3;string4" |awk -F"[;,]" 'NR==1{for(i=2;i&lt;=NF;i++)print $1","$i}'。我刚刚删除了你的单线的{print;next} 部分。
  • @GeorgeVasiliou 请使用您问题中的给定示例进行测试。你将单行传递给我的单行,它只会打印出来而不做任何处理。与您的 column1,column2 相同
【解决方案2】:

这是一个 sed 解决方案,如果只是为了说明它在 awk 中是多么容易(并且因为编写 sed 命令很有趣):

$ sed '1b;:a;s/^\([^,]*\),\([^;]*\);/\1,\2\n\1,/;ta' infile
column1,column2
value1,string1
value1,string2
value1,string3
value1,string4
value2,string11
value2,string22

这是基于观察到,在每一行(第一行之后),; 必须用换行符、第一个单词和逗号替换。

用 cmets 可读:

1b                                   # On first line: jump to end and print
:loop                                # Label to jump to
s/^\([^,]*\),\([^;]*\);/\1,\2\n\1,/  # Substitute one ";" as described above
t loop                               # If the pattern was modified, jump to "loop"

替换命令中的捕获组是“从行首开始的,以外的字符”(第一组)和“,和第一个;之间的;以外的字符”,所以在循环要更改的第一行时,第一个捕获组始终为value1,第二个捕获组在每次迭代中为string1string2 等等。

BSD sed,例如在 MacOS 中发现的,抱怨单行中的分支标签。在这种情况下,命令必须像这样分解:

sed -e '1b;:a' -e's/^\([^,]*\),\([^;]*\);/\1,\2\n\1,/;ta' infile

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-11-26
    • 2022-11-03
    • 1970-01-01
    • 1970-01-01
    • 2018-12-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多