数组的最后一项在循环中无法正确打印
在学习shell文本过滤器时,我制作了一个awk脚本,该脚本通过提供标题内联来格式化CSV文件的输出。
从命令行调用包装程序外壳脚本,而它真正要做的只是包装awk脚本并传递一个作为变量regex
的参数,它是搜索字符串。
该脚本将第一条记录(NR==1
)的字段存储到数组heading
中。在CSV文件的正文中找到包含搜索字符串regex
的记录后,脚本会将标题连接到适当的值。
csv.sh:
#!/bin/bash
awk -f ~/Scripts/csv.awk -v "regex=$1" $2
csv.awk:
BEGIN {FS=",";}
NR==1 {
for (i=1; i<=NF; i++) {
heading[i]=$i;
}
}
NR>1 {
if ($0 ~ regex) {
for (i=1; i<=length(heading); i++) {
if(length($i) > 0) {
print(heading[i] ": " $i)
}
}
print("")
}
}
ships.csv:
name,country,displacement,length,beam,commissioned
Yamato,Japan,65027,256,38.9,16 December 1941
USS Enterprise,United States of America,19800,251.4,33.4,12 May 1938
Bismarck,Germany,41700,251,36,24 August 1940
HMS Dreadnought,United Kingdom,18120,160.6,25,2 December 1906
USS Iowa,United States of America,46000,270.43,32.97,22 February 1943
HMS Vanguard,United Kingdom,45200,248.2,32.9,12 May 1946
$ csv Enterprise ships.csv
name: USS Enterprise
country: United States of America
displacement: 19800
length: 251.4
beam: 33.4
commissioned: 12 May 1938
name: USS Enterprise
country: United States of America
displacement: 19800
length: 251.4
beam: 33.4
: 12 May 1938
在我的Linux计算机(Manjaro)上,输出非常相似。但是实际上,如果我将输出通过管道传输到Mac上的pbcopy
,则在粘贴后确实会显示标题:
name: USS Enterprise
country: United States of America
displacement: 19800
length: 251.4
beam: 33.4
commissioned
: 12 May 1938
答案 0 :(得分:1)
根据格伦的评论,您能不能试一下。
awk 'BEGIN {FS=",";}
{gsub(/\r/,"")}
NR==1 {
for (i=1; i<=NF; i++) {
heading[i]=$i;
}
}
NR>1 {
if ($0 ~ regex) {
for (i=1; i<=length(heading); i++) {
if(length($i) > 0) {
print(heading[i] ": " $i)
}
}
print("")
}
}' Input_file
答案 1 :(得分:0)
将数组传递给length
函数是less portable。
如果您怀疑标题文件可能与实际列不匹配的csv文件杂乱无章,那么一种可移植的方法是将总列数存储在开头,然后像下面这样重复使用:
NR==1 {
headercount=NF; # store the count
for (i=1; i<=NF; i++) {
heading[i]=$i;
}
}
NR>1 {
if ($0 ~ regex) {
for (i=1; i<=headercount; i++) { #Use the count
if(length($i) > 0) {
print(heading[i] ": " $i)
}
}
print("")
}
}
此外,如果您必须处理dos样式的文件结尾,则可以将脚本更改为:
#!/bin/bash
dos2unix -q "$2" # This makes sure that the input file has unix style file endings
awk -f ./csv.awk -v "regex=$1" $2
测试
$ ./csv.sh HMS ships.csv
name: HMS Dreadnought
country: United Kingdom
displacement: 18120
length: 160.6
beam: 25
commissioned: 2 December 1906
name: HMS Vanguard
country: United Kingdom
displacement: 45200
length: 248.2
beam: 32.9
commissioned: 12 May 1946
如果您的标题被篡改,以致它们没有委托列,那么在这种情况下,它也可以无缝地工作。
测试
$ ./csv.sh HMS ships.csv
name: HMS Dreadnought
country: United Kingdom
displacement: 18120
length: 160.6
beam: 25
name: HMS Vanguard
country: United Kingdom
displacement: 45200
length: 248.2
beam: 32.9