将前导零添加到 awk 变量
Posted
技术标签:
【中文标题】将前导零添加到 awk 变量【英文标题】:Add leading zeroes to awk variable 【发布时间】:2011-11-03 04:03:10 【问题描述】:我在 bash 的“for”循环中有以下 awk 命令:
awk -v pdb="$pdb" 'BEGIN file = 1; filename = pdb"_" file ".pdb"
/ENDMDL/ getline; file ++; filename = pdb"_" file ".pdb"
print $0 > filename' < $pdb.pdb
这会读取一系列名为 $pdb.pdb 的文件,并将它们拆分为名为 $pdb_1.pdb、$pdb_2.pdb、...、$pdb_21.pdb 等的文件。但是,我想生成名称如 $pdb_01.pdb、$pdb_02.pdb、...、$pdb_21.pdb 的文件,即向“文件”变量添加填充零。
我尝试过以不同方式使用 printf 都没有成功。非常感谢您的帮助。
【问题讨论】:
你知道这个数字会上升到多高吗?最多2位数吗? 【参考方案1】:以下是使用awk
创建前导零的方法:
# echo 1 | awk ' printf("%02d\n", $1) '
01
# echo 21 | awk ' printf("%02d\n", $1) '
21
将%02
替换为您需要的总位数(包括零)。
【讨论】:
请注意,这仅在您直接将格式化数字打印到输出时才有效。如果您希望在 awk 变量或函数中使用格式化数字,您可能需要使用sprintf
,如另一个答案中所述。
awk ' printf "%0" $2 "d\n", $1 '
在这里工作正常。【参考方案2】:
将输出上的file
替换为sprintf("%02d", file)
。
甚至整个分配filename = sprintf("%s_%02d.pdb", pdb, file);
。
【讨论】:
到目前为止,我已经尝试了第一个选项,它就像一个魅力。谢谢一百万。【参考方案3】:无需使用printf
就可以做到这一点,这很昂贵。第一个参数是要填充的字符串,第二个是填充后的总长度。
echo 722 8 | awk ' for(c = 0; c < $2; c++) s = s"0"; s = s$1; print substr(s, 1 + length(s) - $2); '
如果您事先知道结果字符串的长度,您可以使用简化版本(比如 8 是您的限制):
echo 722 | awk ' s = "00000000"$1; print substr(s, 1 + length(s) - 8); '
两种情况的结果都是00000722
。
【讨论】:
不知道根据什么标准这会更快。在快速测试中,该脚本的 10,000 次迭代耗时 42 秒,而printf
明显更简单的变体耗时 35 秒。【参考方案4】:
这是一个根据参数向左或向右填充零的函数:zeropad(value, count, direction)
function zeropad(s,c,d)
if(d!="r")
d="l" # l is the default and fallback value
return sprintf("%" (d=="l"? "0" c:"") "d" (d=="r"?"%0" c-length(s) "d":""), s,"")
# test main
print zeropad($1,$2,$3)
一些测试:
$ cat test
2 3 l
2 4 r
2 5
a 6 r
测试:
$ awk -f program.awk test
002
2000
00002
000000
它没有经过全面的战场测试,所以奇怪的参数可能会产生奇怪的结果。
【讨论】:
以上是关于将前导零添加到 awk 变量的主要内容,如果未能解决你的问题,请参考以下文章