bash命令,用于通过分隔符将单元格内容拆分为单元格列中的多个行

时间:2017-09-06 09:21:21

标签: bash dataframe

绘制任务。我有数据帧:

x   y1;y2;y3    z1;z2;z3
a   b1;b2       c1;c2

我需要:

x   y1  z1
x   y2  z2
x   y3  z3
a   b1  c1
a   b2  c2

第1列总是有一个实例。单元格中的实例数可以是1到多个,但在列2,3之间总是相等。感谢

2 个答案:

答案 0 :(得分:0)

这样的事情应该成功:

declare -a cols=() # array for individual columns (line fields)
IFS=' ;'           # fields separators

while read -a cols; do
    n=${#cols[@]} # number of fields in current line
    if (( n < 3 || n % 2 != 1 )); then # skip invalid lines
        printf "skipping invalid line: %s\n" "${cols[*]}"
        continue
    fi
    for (( i = 1; i <= n / 2; i += 1 )); do # loop over pairs of fields
        # printf line
        printf "%s %s %s\n" "${cols[0]}" "${cols[i]}" "${cols[n/2+i]}"
    done
done < data.txt

说明:

  • IFSread用于在字段中拆分一行的字符列表。在你的情况下,;似乎是分隔符。
  • read -a cols从单元格0开始,将读取行的字段分配给cols数组。

运行示例:

$ cat data.txt
x   y1;y2;y3    z1;z2;z3
a   b1;b2       c1;c2
$ ./foo.sh
x y1 z1
x y2 z2
x y3 z3
a b1 c1
a b2 c2

答案 1 :(得分:0)

在awk中:

$ awk -F"(\t|;)" '{
    for(i=2;i<=4;i++)
        if($i!="")
            print $1, $i, $(i+3) 
}' file
x y1 z1
x y2 z2
x y3 z3
a b1 c1
a b2 c2

修改:另一个版本:

$ awk -F"(\t+|;)" '{               # FS tabs or semicolon      
    for(i=2;i<=int(NF/2)+1;i++)
        print $1,$i,$(i+int(NF/2))
}' file
x y1 z1
x y2 z2
x y3 z3
a b1 c1
a b2 c2