Unix 递归地从shell中的文件中删除文件名后缀

Unix 递归地从shell中的文件中删除文件名后缀,unix,deployment,filenames,rename,Unix,Deployment,Filenames,Rename,当我们在本地开发时,我们将“.dev”或“.prod”附加到文件中,这些文件应该分别只对开发/生产服务器可用 我想做的是;将站点部署到服务器后,递归地查找带有“.dev”后缀的所有文件(例如),并将其删除(重命名文件)。我该怎么做呢,最好完全在shell中(没有脚本),这样我就可以将它添加到部署脚本中 我们的服务器运行Ubuntu 10.04 for file in `ls *.dev`; do echo "Old Name $file"; new_name=`echo $file | sed

当我们在本地开发时,我们将“.dev”或“.prod”附加到文件中,这些文件应该分别只对开发/生产服务器可用

我想做的是;将站点部署到服务器后,递归地查找带有“.dev”后缀的所有文件(例如),并将其删除(重命名文件)。我该怎么做呢,最好完全在shell中(没有脚本),这样我就可以将它添加到部署脚本中

我们的服务器运行Ubuntu 10.04

for file in `ls *.dev`; do echo "Old Name $file"; new_name=`echo $file | sed -e 's/dev//'` ; echo "New Name $new_name"; mv $file $new_name; done
在我最近使用的一个示例中,此代码查找以new.xml结尾的任何文件,更改文件名中的日期(文件名的格式为xmlEventLog_2010-03-23T11:16:16_PFM_1_1.xml),从名称中删除_new并将文件名重命名为新名称:

for file in `ls *new.xml`; do echo "Old Name $file"; new_name=`echo $file | sed -e 's/[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}/2010-03-23/g' | sed 's/_new//g'` ; echo "New Name $new_name"; mv $file $new_name; done

这是您想要的类型吗?

这是完全未经测试的,但在您选择的类似POSIX的shell中应该可以使用:

remove-suffix () {
    local filename
    while read filename; do
        mv "$filename" "$(printf %s "$filename" | sed "s/\\.$1\$//")"
    done
}

find -name '*.dev' | remove-suffix .dev
注意:在一个或多个文件名包含换行符的非常罕见的情况下,.

尝试此操作(不仅仅是shell,需要
find
mv
实用程序):

如果您有
rename
xargs
实用程序,则可以大大加快速度:

find . '(' -name '*.dev' -o -name '*.prod' ')' -type f -print0 | xargs -0 rename 's/\.(dev|prod)$//'

这两个版本都应该适用于任何文件名,包括包含换行符的文件名。

不会递归到子目录中。并且它不适用于包含任何“特殊”的文件名(空格、换行符、不可打印字符…)。只是尝试提供帮助。我不会再在这个网站上这么做了,冷静。我们试图帮助您改进您的答案,但实际上并没有回答原来的问题。这不是对你的人身攻击,因为这是不对的。(我没有因为它的价值而投反对票。)这已经得到了回答:@Alfredeza:谢谢你指出了这一点——我在那里找不到任何(除了shell脚本)可以实现我想要的功能的东西。不过,下面有一些不错的答案。+1,这比我的好。但是,如果您确实有严格的兼容性需求,您可能想知道POSIX
find
没有
-execdir
-print0
,我相信
“${0%.dev}”
是一种bashism。这似乎很有效;我将's/\.dev$/.prod/'替换为's/\.dev$/',因为我希望完全删除扩展。没有特定的兼容性需求,因此对rename/xargs的依赖性不是问题。谢谢
sh
的主页说明
sh
知道后缀删除
-execdir
可以替换为
-exec
(Linux手册页上说它不太安全),但是
-print0
是无法替换的。
find /fullpath -type f -name "*.dev"|sed 's|\(.*\)\(\.pdf\)|mv & \1.sometag|' | sh
find /fullpath -type f -name "*.dev"|sed 's|\(.*\)\(\.pdf\)|mv & \1.sometag|' | sh