![](/img/trans.png)
[英]How to replace a column of a CSV file with lines from another file in BASH?
[英]BASH: How to print CSV file out with column headers as separate lines
我有一个2行CSV文件。 标题是1行,数据是1行。 这是从资产数据库中提取的,而仅查找一项资产的数据。 但是,请注意,CSV文件可能包含不止2行。
我需要采用CSV(以下示例)并将每个标头条目打印在单独的行上,并将匹配的数据条目打印在同一行上。
样本CSV数据
head1,head2,head3,head4
data1,data2,data3,data4
样品输出
head1 data1
head2 data2
head3 data3
head4 data4
如何简单地做到这一点?
#!/bin/bash
while { read -r line1; read -r line2; } do
IFS=', ' read -r -a array1 <<< "$line1"
IFS=', ' read -r -a array2 <<< "$line2"
for index in "${!array1[@]}"
do
echo "${array1[index]} ${array2[index]}"
done
done < $1
编辑了我以前的答案。 通过嵌套循环,它可以处理多于两行和多列。
仅使用纯bash:
while IFS=", " read a b c d e f g h;do echo -e "$a\t$e\n$b\t$f\n$c\t$g\n$d\t$h";done <<< $(echo $(<data.csv) )
鉴于我想从文件中读取内容,我不喜欢将输出输出到另一个文件的想法,以后我必须清理它,因此我选择了一个关联数组,该数组在BASH v4中可用,仅在内置时才可用命令declare -A
这在BASH v3或更低版本中将不起作用,因为-A
对内置declare
的有效标志无效。
由于已知此文件中只有两行,因此这是一个非常丑陋的解决方案,效果很好。 通过在最终的for循环中添加嵌套的for循环,可以对其进行修改以容纳其他行,但是在输出时,您可能还会遇到其他有关线宽和换行的问题。
NF=$(awk -F, 'NR==1{print NF}' temp.txt)
declare -A temparray
for ((i=1;i<=$NF;++i))
do
temparray[0,$i]+="$(awk -v VAR=$i -F, 'NR==1{print $VAR}' temp.txt)"
done
for ((i=1;i<=$NF;++i))
do
temparray[1,$i]+="$(awk -v VAR=$i -F, 'NR==2{print $VAR}' temp.txt)"
done
for ((i=1;i<=$NF;++i))
do
printf "%-45s %s\n" "${temparray[0,$i]}" "${temparray[1,$i]}"
done
unset temparray
使用bash,这仅在您使用两行时有效。
n=0
while read line;do echo ${line//,/\\n} > file$n ; let n++;done < L
paste file0 file1
head1 data1
head2 data2
head3 data3
head4 data4
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.