我有一个以分号分隔的 csv 文件和一个进行一些详细说明的 Korn shell 脚本。我正在寻找了解这两条指令在 Korn shell 中的作用:
num_rec=`cat test.csv |wc -l|tr -d " " | nawk '{printf("%0.6d\n", $1) }'`
num_rec=`expr $num_rec + 2 | nawk '{printf("%0.6d\n", $1) }'`
看起来是两条使用串联的指令,但最终的结果是什么呢? nawk 命令中的“$1”是什么?
答案1
让我们分解这两个命令
num_rec=`cat test.csv |wc -l|tr -d " " | nawk '{printf("%0.6d\n", $1) }'`
是一个复合命令:A |乙| C | D
- 答:
cat test.csv
只是cats文件test.csv(也是一个UUOC,“Useless Use Of Cat”) - B:
wc -l
将从其输入(stdin)中计算行数,这里是 test.csv 的内容。所以它会计算“test.csv”中的行数[...注意如果 test.csv 的最后一行缺少最后的“换行符”,则最后一行将不被计算在内...] - C:
tr -d " "
: tr 将删除所有出现的“ ”(空格),wc -l 使用它来填充行号的输出。这将确保仅保留数字(和终止换行符) - 最后的 D:
nawk '{printf("%0.6d\n", $1)'
:这里 $1 位于 awk 内部,表示“当前行的第一个字段”。对于它接收到的每一行,此 nawk 将仅打印第一个字段并对其进行数字格式化:作为 INT (%d),但在开头用 0 填充以使其至少有 6 位数字(此处的“.”被忽略) ,据我所知...与 %0.6f 相比,它输出逗号后有 6 位数字的浮点数)
第二行:
num_rec=`expr $num_rec + 2 | nawk '{printf("%0.6d\n", $1) }'`
只需在数字上加 2(注意:对于 expr 来说 000008 是可以的,并且将被视为“8”,而在 shell 中它将被视为错误的八进制数)并以相同的方式再次格式化它。
所有这些都可以简化为:
num_rec=$(printf "%0.6d\n" "$(( $(wc -l < test.csv) + 2 ))")
所以这一切所做的就是:计算 .csv 的行数(无论该行的内容...),然后添加 2,并将结果放入“num_rec”中,前面带有“0”至少 6 位数字。
例如:32 行的 test.csv 文件将放入 num_rec:000034
(警告:shell 中的 0nnnn 通常被视为八进制数,因此之后必须非常小心地处理 $num_rec...)
答案2
它们是由新手编写的命令,这些新手要么自 90 年代初以来就没有学过任何东西,要么正在遵循那个时代的 HOWTO。最好写成:
num_rec=$(wc -l <test.csv)
num_rec=$(printf "%0.6d" $(( num_rec + 2 )) )
这使用命令替换获取test.cv
使用的行数wc -l
(通过重定向,这样wc
就不会打印文件名和行数)。
然后它再次使用命令替换,这次使用printf
格式字符串对行计数进行零填充,使其具有 6 位的固定宽度,并使用 shell 算术将 2 添加到$num_rec
。
$1
原始命令中的指awk
的是输入的第一个字段(在本例中为 的行数wc
)