2015-12-28 31 views
-2

我有一个文件目录,其中一些以下划线结尾。Bash重命名字符串中的最后一个下划线

我想测试每个文件,看它是否以下划线结尾,然后去掉下划线。

我目前运行下面的代码:

for file in *;do 
    echo $file; 
    if [[ "${file:$length:1}" == "_" ]];then 
     mv $file $(echo $file | sed "s/.$//g"); 
    fi 
done 

但它似乎并没有被重命名使用下划线的文件。例如,如果我有一个名为all_indoors_的文件,我期望它能给我all_indoors

+0

你只是想删除下划线,没有别的?另外,'$ length'在哪里定义? – fedorqui

+0

你的意思是带* off?删除下划线,或下划线和其余文本? –

+1

@fedorqui不知道,认为我犯了一个错误:-) – andlrc

回答

0

可以使用,这将是递归的:

while read f; do 
    mv "$f" "${f:0:-1}"; # Remove last character from $f 
done < <(find . -type f -name '*_') 
+0

如果文件名中有新行,这将会中断。我建议循环遍历glob而不是使用find在这里。 – hek2mgl

0

虽然不是纯bash的方法,你可以使用rename.ul(由Larry Wall写,后面的人perl)。重命名不是默认Linux环境的一部分,但是是util-linux的一部分。

您使用与重命名:

rename perlexpr files 

(一些标志ommitted)。

所以,你可以使用:

rename 's/_$//' * 

,如果你想删除所有的字符,包括和下划线后。

正如@ hek2mgl指出的那样,有多个rename命令(请参阅here),所以首先测试是否选择了正确的命令。

+0

来自util-linux的'rename'命令*不能用于perl正则表达式! (我也需要认识到...;)) – hek2mgl

+0

@ hek2mgl:那么为什么文档中指定了这样的内容呢? –

+0

如果你的'man rename'这样说,它不是'util-linux'。 '重命名-V'给你什么? '从util-linux 2.26.2'重命名?我想你是指http://search.cpan.org/dist/rename/。漂亮的工具!但不幸的是,它不是'util-linux'的一部分。 – hek2mgl

1

只需使用一个regex to check the string

for file in * 
do 
    [[ $file =~ "_$" ]] && echo mv "$file" "${file%%_}" 
done 

一旦确认它按预期工作,除去echo使得mv命令执行!


它甚至可能是清洁剂使用*_,使for将刚刚超过与_结尾的名称的文件回路,如hek2mgl暗示的意见。

for file in *_ 
do 
    echo mv "$file" "${file%%_}" 
done 
+2

我喜欢这个答案,但是为什么不用''for file in * _'?这将为您节省正则表达式检查。 – hek2mgl

+0

@ hek2mgl你是这里最聪明的方法:)我没有想过,用它更新我的答案! (或者随意添加自己的答案,当然)。 – fedorqui

+1

不,不..去吧! :) – hek2mgl

相关问题