【发布时间】:2019-04-16 03:26:34
【问题描述】:
数组的最后一项不能从循环中正确打印
在学习 shell 文本过滤器时,我制作了一个小 awk 脚本,通过提供内联标题来格式化 CSV 文件的输出。
从命令行调用包装器 shell 脚本,它真正做的只是包装 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
【问题讨论】:
-
i<=length(heading)看起来很可疑。我猜你需要i<=NF -
您的数据文件具有 DOS 风格的
\r\n行结尾。 “commissioned”这个词实际上是commissioned\r,因此将光标发送到冒号之前的行首并打印值。 -
格伦我不能为你的评论投票
-
如果
length(heading)不等于NF那么你就有问题所以i<=length(heading)可以简单地写成i<=NF。同样if(length($i) > 0)相当于只写if ($i!="")。
标签: awk