用前导0递增bash中的数字

时间:2013-05-24 14:20:38

标签: bash shell variables if-statement

我是一个非常新手来编写脚本,我正在尝试编写一些代码来解析和操作我正在处理的文件。

我需要在一个文件中为一堆不同的时间增加和减少一分钟的时间。当时间是例如2:04或14:00时,我的问题就出现了。

文件示例:

2:43
2:05
15:00

我目前从我的bash脚本中摘录的是这样的

for x in `cat $1`;
  do minute_var=$(echo $x | cut -d: -f2);
  incr_min=$(($minute_var + 1 | bc));
  echo $incr_min;
done

当前结果:

44
6
1

必填结果:

44
06
01

任何建议

8 个答案:

答案 0 :(得分:3)

使用printf

incr_min=$(printf %02d $(($minute_var + 1 )) )

如果仅涉及整数,则不需要bc

答案 1 :(得分:1)

这可以满足您的要求吗?

kent$  echo "2:43
2:05
15:00"|awk -F: '{$2++;printf "%02d\n", $2}'
44
06
01

答案 2 :(得分:1)

更新#2

您的脚本存在一些问题。首先应使用`cat file``<file`,而不是$(<file)。只需fork打开文件即可免除一次execbash电话。另一方面,调用cutbc(以及printf)也不需要,因为bash内部具有适当的功能。因此,您可以再次节省一些forkexec

如果输入文件很大(大于cca 32 KiB),那么for - 循环线可能太大而无法由bash处理,因此我建议使用while - 而是循环并逐行读取文件。

我可以在纯bash(应用Atle的substr解决方案)中建议这样的事情:

while IFS=: read hr min; do
  incr_min=$((1$min+1)); #Octal problem solved
  echo ${incr_min: -2}; #Mind the space before -2!
  #or with glennjackman's suggestion to use decimal base
  #incr_min=0$((10#$min+1))
  #echo ${incr_min: -2};
  #or choroba's solution improved to set variable directly
  #printf -v incr_min %02d $((10#$min+1))
  #echo $incr_min
done <file

输入文件

$ cat file
2:43
2:05
15:00
12:07
12:08
12:09

输出:

44
06
01
08
09
10

也许printf -v是最简单的,因为它将结果放在一个步骤中。

来自tripleee的好问题,如果结果是60,会发生什么。

答案 3 :(得分:1)

while IFS=: read hour min; do 
    printf "%02d\n" $((10#$min + 1))
done <<END
2:43
2:05
15:00
8:08
0:59
END
44
06
01
09
60

对于下一个小时的分钟包,请使用具有时间功能的语言,例如gawk

awk -F: '{
    time = mktime("1970 01 01 " $1 " " $2 " 00")
    time += 60
    print strftime("%M", time)
}' 
perl -MTime::Piece -MTime::Seconds -nle '
    $t = Time::Piece->strptime($_, "%H:%M");
    print +($t + ONE_MINUTE)->strftime("%M");
'

答案 4 :(得分:0)

使用printf重新格式化输出为零填充,2宽:

incr_min=$(printf %02d $incr_min)

答案 5 :(得分:0)

这是

的解决方案
  • 将秒数从59包裹到0
  • 完全符合POSIX标准 - 没有bashisms!
  • 不需要单个叉子因此非常快
$ cat x
2:43
2:05
2:08
2:09
15:00
15:59
$ while IFS=: read hr min; do
   printf '%02d\n' $(((${min#0}+1)%60))
done < x
44
06
09
10
01
00

答案 6 :(得分:0)

试试这个:

for x in $(<$1); do
    printf "%02d\n" $(((${x#*:}+1)%60));
done

答案 7 :(得分:-1)

用0填充,得到最后两个字符:

for x in `cat $1`;
  do minute_var=$(echo $x | cut -d: -f2);
  incr_min=0$(($minute_var + 1 | bc));
  echo ${incr_min: -2:2};
done