将前导零添加到 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 变量的主要内容,如果未能解决你的问题,请参考以下文章

将前导零添加到 Spark 数据框中的列 [重复]

添加前导零 Python [重复]

如何在 C sprintf 中添加用户定义的变量前导零?

Python将前导零添加到时间字段[重复]

如何将前导零添加到国家号码?

如何将前导数字标识符(不一定为零)添加到 r 中的字符串