如何在 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
因为您的示例输入似乎没有在字段中包含空格。
下面是文件中的示例数据
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
因为您的示例输入似乎没有在字段中包含空格。