【问题标题】:Bash turning single comma-separated column into multi-line stringBash 将单个逗号分隔的列转换为多行字符串
【发布时间】:2016-01-29 06:31:34
【问题描述】:

在我的输入文件中,列是制表符分隔的,每列内的值是逗号分隔的。

我想打印第一列与第二列的每个逗号分隔值。

Mary,Tom,David   cat,dog
Kevin   bird,rabbit
John    cat,bird
...

对于第二列中的每条记录(例如cat,dog)我想拆分 记录到 [ cat, dog ] 数组中并将其交叉打印到 第一列。给出输出(仅针对这一行)

Mary,Tom,David   cat
Mary,Tom,David   dog

整个文件的输出应该是:

Mary,Tom,David   cat
Mary,Tom,David   dog
Kevin   bird
Kevin   rabbit
John    cat
John    bird
...

如果我想使用 awk 或 sed,有什么建议吗? 谢谢

【问题讨论】:

  • 这个问题没有任何意义。
  • @123 我需要以这种方式制作文件以供以后处理,只是想知道使用 bash 是否会有一些更简单的方法......或者我应该举更多例子吗?
  • 他的意思是这个问题是一个不清楚的不是你必须使用这种格式的兴趣。输出未显示您的解释指定的内容。制表符和逗号对您来说是什么?逗号和制表符通常是列分隔符(CSV 系列)
  • 所以你需要将\t转换成\n,转换成\t或者几个空格?
  • @NeronLeVelu,我修改了例子让它更友好,希望你能把输入和输出联系起来

标签: bash awk sed multiple-columns comma


【解决方案1】:

使用 awk

awk '{split($2,a,",");for(i in a)print $1"\t"a[i]}' file

用逗号分割第二列,然后对于每个分割值,打印第一列和那个值

也在 sed 中

sed ':1;s/\(\([^\n]*\t\)[^\n]*\),\{1,\}/\1\n\2/;t1' file

【讨论】:

  • split($2,a,",") 是否意味着将 $2 拆分为数组 a ?
  • @一旦是,并带有分隔符,
【解决方案2】:

使用 awk

awk '{split($2, aEl, ","); for (Eli in aEl) print $1 "\t" aEl[ Eli]}' YourFile

使用 sed

sed 'H;s/.*//;x
:cycle
   s/\(\n\)\([^[:cntrl:]]*[[:blank:]]\{1,\}\)\([^[:cntrl:]]*\),\([^,]*\)/\1\2\3\1\2\4/;t cycle
s/.//' YourFile

【讨论】:

  • 下面/(上面)还有另一个 sed 答案,效果很好,但我看不懂
【解决方案3】:

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

sed -r 's/^((\S+\s+)[^,]+),/\1\n\2/;P;D' file

该过程可以分解为三个命令:替换、打印和删除。将第二个字段中的每个 , 替换为换行符和第一个字段以及以下空格。然后打印到包含换行符并删除到包含换行符并重复。关键命令是D,它将重新调用以前的命令,直到模式空间完全为空。

【讨论】:

  • 漂亮的sed版本的答案!!但是我太笨了,即使你的解释也无法理解
  • 我可以问一下 S、s 和 P ..吗?
  • 很好地使用PD
  • @once \S 是非空格,\s 空格,P 打印第一行,D 删除第一行(当前缓冲区的)
  • @once \s 匹配空白并且是[[:space:]] 的同义词,\S 匹配非空白并且是[^[:space:]] 的同义词。 N, P and D 的使用示例参见here
【解决方案4】:

process.sh

#!/bin/bash

while read col_one col_two; do
  IFS=, read -a explode <<< "$col_two";
  for val in "${explode[@]}"; do
    printf "%s\t%s\n" "$col_one" "$val";
  done;
done <"$1";

input.txt 为

Mary,Tom,David   cat,dog
Kevin   bird,rabbit
John    cat,bird

输出

$ ./process.sh input.txt 
Mary,Tom,David  cat
Mary,Tom,David  dog
Kevin   bird
Kevin   rabbit
John    cat
John    bird

【讨论】:

  • explode 只是我读入的数组名称(让我想起了 php 函数 explode ,它在功能上类似于这个 bash 脚本)
猜你喜欢
  • 2012-02-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-13
  • 2012-09-04
相关资源
最近更新 更多