我在目录(linux)中有很多文件。
示例:
.0130. .0230. .0330. .0430. ....2330.. ..2430.
这里0930代表小时并且从1改为24(30不改变),日期也会改变。小时代表
.0030. .0130. .0230. .0330. .... .2230.
我想在文件名中替换此部分(仅此部分),减去1小时
so .0130. becomes .0030.
.0230. becomes .0130.
并且不要触摸文件名中的任何其他数字。
2430. becomes .2330.
..............等等
rename -n 's/(\d+)(\.vgf.img)/($1-1).$2/e' file300.data.20141231.MC.0930.vgf.img
我试过了:
file300.data.20141231.MC.929.vgf.img
但是回复了这个:
.0930.
所以.929.
成了.0830.
,这不是我想要的。我寻找:{{1}}
答案 0 :(得分:3)
正则表达式对于这样的任务并不是很好,并且使用awk或perl脚本会更容易。但是,如果你真的想要,你仍然可以在sed中完成它! =)
在sed中没有减少数字的简单方法,但你可以模仿它:
#!/bin/sed -f
# Replace number XX from line
# "/data/2014/file300.data.20141231.MC.XX30.vgf.img"
# with decremented number (XX-1)
# zero is not changed
# copy filename to hold space
h
# remove everything that is not a number
s/.*MC\.//
s/30\.vgf.*//
# ensure that we don't have leading zeroes
s/^0*//
# here all the magic begins, decrementing
# we need to move all trailing zeroes to begin of number
# we do it using cycle:
# clear test condition
t b
: b
# if we have zero - move it
/0$/{
# remove from end
s/0$//
# append to begin
s/^/0/
}
# if substitution was made - continue cycle
t b
# now we have nonzero at the end, decrement it
s/1$/0/
s/2$/1/
s/3$/2/
s/4$/3/
s/5$/4/
s/6$/5/
s/7$/6/
s/8$/7/
s/9$/8/
# here we change number of digits in our number, this needs to be done only
# when number was of type 10*, in that case after all our permutations it is
# represented as line of all zeroes - just remove one.
/^0*$/s/0//
# another cycle to put zeroes back at end
t e
: e
/^0/{
# remove from beginning
s/^0//
# add to end, as 9
s/$/9/
}
t e
# Now we have decremented number in pattern space and original filename in hold
# format number as two-digit:
s/^$/00/
s/^.$/0&/
# append it to hold space
H
# switch hold and pattern
x
# now we manipulate string like "$filename\nXX" where XX is our decremented
# number.
# Replace number in filename with decremented one
s/\(.*MC\.\)..\(30.*\).\(..\)/\1\3\2/
答案 1 :(得分:1)
我最初把它写成一个有点诙谐的回答并且不打算发布,但看到Yury的解决方案(这很棒!)我觉得有必要将其作为至少可能有用的。
您没有充分指定问题,但假设您的文件都有结尾“$ {timestamp} .vgf.img”(实际上,假设时间戳后名称中存在两个点): / p>
echo /data/2014/file300.data.20141231.MC.0930.vgf.img |
awk '{a=substr($(NF-2),0,2); $(NF-2)=(a-1)"30"} 1' FS=. OFS=.
答案 2 :(得分:0)
您需要减去100而不是1,才能从930中得到830。然后,可以使用sprintf
来格式化带前导零的结果。以下命令将按预期运行
~$ rename -n 's/(\d+)(\.vgf.img)/(sprintf("%04d", ($1 - 100))).$2/e' file300.data.20141231.MC.0930.vgf.img
rename(file300.data.20141231.MC.0930.vgf.img, file300.data.20141231.MC.0830.vgf.img)