2013-03-21 102 views
0

我有一大堆的目录,例如重命名多个目录一次

2013_03_12_18_26_am 
2013_03_12_18_26_cu 
2013_03_12_18_26_ig 
2013_03_12_18_26_mdf 
2013_03_12_18_26_pih 
2013_03_12_18_26_tn 
2013_03_12_18_26_an 
2013_03_12_18_26_cv 
2013_03_12_18_26_ik 
2013_03_12_18_26_mhr 
2013_03_12_18_26_pnb  
2013_03_12_18_26_to 

的什么我想要做的就是它们重命名为他们的最后两个字符,例如: 2013_03_12_18_26_am到我, 我知道我可以一个接一个地做mv 2013_03_12_18_26_am am但这需要很长时间。这可以从shell脚本中实现吗?

我希望在最后一个“_”之后的所有内容成为新目录的名称。

+1

有时候,也有最后'_'后三个字符。你确定你想要最后两个字吗? – choroba 2013-03-21 16:57:27

+0

对不起,我想在最后的每一件事_ – 2013-03-21 16:58:38

回答

1

这个假设你的所有文件夹都在一个目录中(并且只有全部)。所以,要小心......

原文:

marks-mac-pro:test mstanislav$ ls 
2013_03_12_18_26_am 2013_03_12_18_26_an 2013_03_12_18_26_cu 2013_03_12_18_26_cv  2013_03_12_18_26_ig 2013_03_12_18_26_ik 2013_03_12_18_26_mdf 2013_03_12_18_26_mhr 2013_03_12_18_26_pih 2013_03_12_18_26_pnb 2013_03_12_18_26_tn 2013_03_12_18_26_to 

Shell脚本:

marks-mac-pro:test mstanislav$ for i in `ls .`; do NEW=`echo $i | cut -d_ -f6`; mv $i $NEW; done 

结果:

marks-mac-pro:test mstanislav$ ls 
am an cu cv ig ik mdf mhr pih pnb tn to 

请做它的实际数据之前进行测试,只是确保;确定。再次,只能在一个目录中进行此操作,只需要重命名文件夹,或者将第一部分重新编写为更具体的第一部分。

2

如果按照以上表格中的所有目录,然后在bash,那么你可以使用下面的变量subsitituion最终_

var=2013_03_12_18_26_am 
echo ${var##*_} #am 

后的字符提取然后,您可以重命名文件夹中的所有目录:

for dir in *_*; do #as there may be more than 2 chars after final _ 
    new_dir=${dir##*_} 
    mv $dir $new_dir 
done 

当然,您需要添加检查以确保您只是在移动目录,而且您不覆盖任何内容。

1
for d in *_?? 
do 
    newd=$(expr $d : '.*_\([a-z][a-z]*\)') 
    mv $d $newd 
done 
3

我注意到那些目录名没有空格或其他特殊字符。所以你可以尝试:

ls|xargs -n1 |sed -r 's/(.*_)(.*)/mv & \2/' 

打印mv厘米为你。如果你认为所有的命令都是正确的,那么你只需将它管到|sh

注意,ls部分,你可以改变只得到那些目录。

+0

这是我的解决方案。一个使用所有正确的unix工具的单线程。 – 2013-03-21 17:18:55

+0

@JonathanCairns个人我觉得像xargs和sed在这种情况下有过度杀伤力,当时有完美的内置工具可以完成这项工作,但是对于他自己的工作。 – cmh 2013-03-21 17:44:45

+0

@cmh你是对的,它只是偏好,但我发现它尝试从命令行使用bash构造(例如尝试在合适的位置使用分号)是一个真正的痛苦。只要它完成了工作,虽然... – 2013-03-21 17:48:57

0

我喜欢这个重命名命令,这使Perl的正则表达式,像这样:

rename 's/.*([a-z]{2})$/$1/' *