如何使用花括号展开创建前导零的序列


45

当我使用以下命令时,将得到预期的结果:

$ echo {8..10}
8 9 10

我如何以一种简单的方式使用该大括号扩展,以获取以下输出?

$ echo {8..10}
08 09 10

我现在可以使用seq(没有尝试过)获得它,但这不是我想要的。

有用的信息可能是我仅限于此bash版本。(如果您有zsh解决方案,但没有bash解决方案,请也分享)

$ bash -version
GNU bash, version 3.2.51(1)-release (x86_64-suse-linux-gnu)

我在这里找到的bash 3中有一些这样做的提示:mywiki.wooledge.org/BashFAQ/018但是,此处概述的方法并不方便。
伯恩哈德

Answers:


70

给第一个数字加上前缀0以强制每个术语具有相同的宽度。

$ echo {08..10}
08 09 10

从Brace Expansion的bash手册页部分:

提供的整数可以加0前缀,以强制每个术语具有相同的宽度。当x或y以零开头时,shell会尝试强制所有生成的项包含相同数量的数字,并在必要时进行零填充。

另外请注意,您可以使用seq-w选项,通过填充与领先的零相等宽度:

$ seq -w 8 10
08
09
10

$ seq -s " " -w 8 10
08 09 10

如果需要更多控制,甚至可以指定printf样式格式:

$ seq -s " " -f %02g 8 10
08 09 10

8
echo {08..10}但是,在刚刚找到解决方案之后,它仅在bash版本4及更高版本中引入。
2013年

令bash那样做让我有些不舒服。对于一堆实用程序(例如perl),前导零表示八进制数。我想您通常不想要八进制数序列...
kurtm

5
应当注意的是,你还可以前缀后,给予当数seq-w像这样开关:seq -w 003生成数字001,002,003和
SLM

@kurtm不必担心前导零。当某些东西试图解析数字时,这可能会受到伤害。真正有用的是生成一个文件名序列foo_00001.someextension,其中几乎所有排序上下文都提供合理的排序。
斯特凡纳·古里科

9

如果您使用printf

printf "%.2d " {8..10} 

这将强制为2个字符并添加前导0。如果需要3个数字,则可以更改为“%.3d”。


感谢您的回答。我知道该printf解决方案,但实际上并没有使它变得更容易。我希望有一些可以完成工作的隐藏技巧:)
Bernhard

这是看起来足够通用的唯一答案,足以处理要填充号码起源的任何情况。我在遍历文件时使用计数器。这个printf解决方案完美地零填充,而其他所有解决方案似乎都集中在生成零填充数字而不是对现有数字进行零填充。
mayyypile 2015年

7

使用以恒定数字开头的范围,并去除该数字:

echo \ {108..110} | sed 's/ 1//g'

或不使用外部命令:

a=({108..110}); echo "${a[@]#1}"

在for循环中使用:

for x in {108..110}; do
  x=${x#1}
  
done

尽管在这种情况下,while循环会更清晰,并且可以在任何POSIX shell中使用:

x=8
while [ $x -le 10 ]; do
  n=$((100+x)); n=${n#1}
  
  x=$((x+1))
done

我接受了其他答案之前的答案,因为它满足了Bash 3.x的要求。尤其是我for无论如何都需要循环。
Bernhard

6

我具有与原始海报(GNU bash, version 3.2.51(1)-release)相同的bash版本{08..12},但不适用于我,但以下内容可以实现:

for i in 0{8..9} {10..12}; do echo $i; done
08
09
10
11
12

有点乏味,但是它确实适用于bash的OP版本(我认为是更高版本)。


我没想到这个解决方案(虽然在我来说,我其实也想编号0001 1000,但你当然原则的作品。
伯恩哈德

1

作为参考,我认为自动固定宽度仅在最新版本的bash中发生:

$ bash -version
GNU bash, version 3.2.25(1)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2005 Free Software Foundation, Inc.

$ echo test{00..05}
test0 test1 test2 test3 test4 test5

-3
for i in $(seq -s " " -f %0${zeros}g $ini $fin); do ....;done

zeros,ini和fin是vars,所以它很容易,你只写了你在“ zeros”中说的零,以便ini fin不会出现问题;)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.