如何在 unix 中将列值转换为行

How to make column values to rows in unix

下面是文件中的示例数据

4 列以 TAB 分隔,最后一列作为值以逗号分隔。 第 3 列实际上显示了第 4 列中值的数量。

6338838 ESR 3   173812,10547556,10518181
6338822 ESR 2   7219086,12761162

预期输出:

6338838 ESR 3   173812
6338838 ESR 3   10547556
6338838 ESR 3   10518181
6338822 ESR 2   7219086
6338822 ESR 2   12761162

尝试过使用 AWK,但无法正常工作。

原生 bash:

while IFS=$'\t' read -r one two three four; do
    IFS=, read -r -a pieces <<<"$four"
    for piece in "${pieces[@]}"; do
      printf '%s\t%s\t%s\t%s\n' "$one" "$two" "$three" "$piece"
    done
done <yourfile

这应该有效:

awk '{n = split(,x,","); for (i = 1; i <= n; ++i) {printf "%s %s %s %s\n", , , , x[i]} }' yourfile

使用 GNU awk:

awk 'BEGIN{FS=OFS="\t"} {c1to3= FS  FS ; columns=split(,array,","); for(i=1; i<=columns; i++) print c1to3,array[i]}' file

或更短:

awk -v OFS='\t' '{columns=split(,array,","); for(i=1; i<=columns; i++) print ,,,array[i]}' file

awk 'BEGIN{OFS="\t"} {c=split(,a,","); NF=3; for(i=1; i<=c; i++) print [=12=],a[i]}' file

输出:

6338838 ESR     3       173812
6338838 ESR     3       10547556
6338838 ESR     3       10518181
6338822 ESR     2       7219086
6338822 ESR     2       12761162

这是另一个 awk,没有引用未使用的字段。

$ awk '{n=split($NF,a,","); 
        for(i=1;i<=n;i++) 
          {sub($NF"$",a[i]); 
           print}}' file.t

编辑: 在这里简单地使用 gsub 去掉逗号怎么样:)

awk -F" +" '{gsub(",",ORS  OFS  OFS  OFS,)} 1' Input_file | column -t

如果您的 Input_file 是制表符分隔的,请将 -F 更改为 -F"\t"



如何简单地使用 awk-F 并根据字段值打印。

awk -F" +|," '{for(i=4;i<=NF;i++){print ,,,$i}}'  Input_file

在上面的代码中附加 | column -t,以防您需要 TAB 分隔的输出。

根据 Cyrus 和 Ghoti 的评论,现在也添加以下内容,以防您的 Input_file 是 TAB 分隔的。

awk -F '[\t,]' -v OFS='\t' '{for(i=4; i<=NF; i++) print ,,,$i}' Input_file

我喜欢这些 "who can do it shorter" 比赛。 :-)

如果我们想使用 3 美元起的商品数量,我们可以这样做:

awk '{split(,a,",");for(i=1;i<=;i++){=a[i];print}}' OFS='\t' input.txt

但下面的代码产生了类似的结果,但代码字节数更少。输出的顺序与 $4 中的子字段相反。

awk '{for(i=split(,a,",");i;i--){=a[i];print}}' OFS='\t' input.txt

懒得设置 FS 因为您的示例输入似乎没有在字段中包含空格。