我对 Shell 脚本很陌生。现在我正在尝试找出一个 shell 脚本代码,它允许我读取 .csv 文件的所有行并仅获取每行的列标题。
对于每一行,某些列上标记有“X”(表示该行存在该名称)。我想开发一个脚本,在给出第一行的名称(例如“row1”)后,输出将为我提供标记为“X”的列标题的相应名称。这是一个 CSV 文件,因此未标记“X”的列只是带有 ; 的空白。分隔符。
输入
Index,Name1,Name2,Name3,Name4
row1,X,,X
row2,,,X,
row3,X,X,X,
如果我搜索“row1”,输出将是
输出
row1 Name1 Name3
如果我搜索“row3”,输出将是
row3 Name1 Name2 Name3
我希望输出以制表符分隔,但如果不可能,那么逗号分隔也可以。我尝试通过首先在行名称上使用 grep 然后通过管道输出来实现此目的。但是,我不确定如何编写一个脚本,如果标记了“X”,该脚本将打印出标题的名称。我有一个想法,可以使用 和 的一些东西grep -w 'row1'
,awk -F , 'NR==1 { for (i=1;i<=NF;++i) if ($i=="X") { n=i;print $n }}'
但我不确定如何将它们串在一起。
任何帮助将不胜感激!
答案1
将标头拆分为一个数组,然后从那里使用它们,例如:
获取模式.awk
BEGIN { FS="," }
NR==1 { split($0, colhead); next }
$1 ~ pat {
printf "%s", $1
for (i=2; i<=NF; i++) {
if ($i ~ /X/)
printf "\t%s", colhead[i]
}
print ""
}
像这样运行它,例如:
awk -f getpattern.awk pat='row1|row3' infile.csv
输出:
row1 Name1 Name3
row3 Name1 Name2 Name3
答案2
我会使用专用的csv
解析器,例如python's
csv
模块会这样做:
import csv
with open('file.csv') as csvfile:
reader = csv.DictReader(csvfile)
for row in reader:
print(row["Index"], *[item[0] for item in row.items() if item[1] == "X"], sep=" ")
输出:
row1 Name1 Name3
row2 Name3
row3 Name1 Name2 Name3