简体   繁体   中英

BASH: How to print CSV file out with column headers as separate lines

I have a 2-line CSV file. 1 line is the header, one line is the data. This was pulled from an asset database while looking for data for just one asset. However, please note that the CSV file could conceivably contain more than just 2 lines.

I need to take the CSV (example below) and print each header entry on a separate line, with the matching data entry on the same line.

Sample CSV data

head1,head2,head3,head4
data1,data2,data3,data4

Sample output

head1   data1
head2   data2
head3   data3
head4   data4

How can this be done simply?

#!/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

Edited my previous answer. By nesting loops it handles more than two lines and multiple columns.

仅使用纯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) )

Given that I wanted to read in from a file, I did not like the idea of output to another file which I would later have to clean up, hence I went with an associative array, which is available in BASH v4 and up only with builtin command declare -A

This will not work in BASH v3 or lower as -A is not a valid flag to the declare builtin.

Since there are known to only be 2 lines in this file, this is a fairly ugly solution that works well. It could be modified to accommodate additional lines, by adding a nested for loop within the final for loop however then you could run into other issues with line width and line wrapping, upon output.

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

Using bash, this works only if you what two lines.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM