25

我在 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 没有成功。帮助将不胜感激。

4

4 回答 4

37

以下是如何创建前导零awk

# echo 1 | awk '{ printf("%02d\n", $1) }'
01
# echo 21 | awk '{ printf("%02d\n", $1) }'
21

替换%02为您需要的总位数(包括零)。

于 2011-08-24T20:53:28.363 回答
36

用 替换file输出sprintf("%02d", file)

甚至是整个分配filename = sprintf("%s_%02d.pdb", pdb, file);

于 2011-08-24T20:51:33.147 回答
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

于 2019-03-20T18:38:11.223 回答
1

这是一个根据参数向左或向右填充零值的函数: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

它没有经过全面的战场测试,所以奇怪的参数可能会产生奇怪的结果。

于 2017-08-06T10:22:49.663 回答