我在a_dbg.txt, b_dbg.txt ...
系统中有Suse 10
这样的文件。我想写一个bash shell脚本,它应该通过从它们中删除“_dbg”来重命名这些文件。
Google建议我使用rename
命令。所以我在rename _dbg.txt .txt *dbg*
CURRENT_FOLDER
命令
我的实际CURRENT_FOLDER
包含以下文件。
CURRENT_FOLDER/a_dbg.txt
CURRENT_FOLDER/b_dbg.txt
CURRENT_FOLDER/XX/c_dbg.txt
CURRENT_FOLDER/YY/d_dbg.txt
执行rename
命令后,
CURRENT_FOLDER/a.txt
CURRENT_FOLDER/b.txt
CURRENT_FOLDER/XX/c_dbg.txt
CURRENT_FOLDER/YY/d_dbg.txt
它没有递归,如何使这个命令重命名所有子目录中的文件。与XX
和YY
一样,我将拥有许多名称不可预测的子目录。而且我的CURRENT_FOLDER
也会有其他文件。
答案 0 :(得分:111)
您可以使用find
递归查找所有匹配的文件:
$ find . -iname "*dbg*" -exec rename _dbg.txt .txt '{}' \;
编辑: '{}'
和\;
是什么?
-exec
参数使找到每个匹配文件的执行rename
。 '{}'
将替换为文件的路径名。最后一个标记\;
仅用于标记exec表达式的结尾。
在查找的手册页中很好地描述了所有内容:
-exec utility [argument ...] ;
True if the program named utility returns a zero value as its
exit status. Optional arguments may be passed to the utility.
The expression must be terminated by a semicolon (``;''). If you
invoke find from a shell you may need to quote the semicolon if
the shell would otherwise treat it as a control operator. If the
string ``{}'' appears anywhere in the utility name or the argu-
ments it is replaced by the pathname of the current file.
Utility will be executed from the directory from which find was
executed. Utility and arguments are not subject to the further
expansion of shell patterns and constructs.
答案 1 :(得分:12)
我编写的小脚本将.txt扩展名的所有文件替换为/ tmp下的.cpp扩展名和递归子目录
#!/bin/bash
for file in $(find /tmp -name '*.txt')
do
mv $file $(echo "$file" | sed -r 's|.txt|.cpp|g')
done
答案 2 :(得分:12)
为了递归重命名,我使用以下命令:
find -iname \*.* | rename -v "s/ /-/g"
答案 3 :(得分:11)
使用bash:
shopt -s globstar nullglob
rename _dbg.txt .txt **/*dbg*
答案 4 :(得分:2)
上面的Scipt可以写成一行:
find /tmp -name "*.txt" -exec bash -c 'mv $0 $(echo "$0" | sed -r \"s|.txt|.cpp|g\")' '{}' \;
答案 5 :(得分:1)
find -execdir rename
重命名带有正则表达式的文件和目录
如果您要使用正则表达式而不是仅使用后缀来重命名文件和目录,那么这是一个很好的模式:
find-rename-regex() (
set -eu
find_and_replace="$1"
PATH="$(echo "$PATH" | sed -E 's/(^|:)[^\/][^:]*//g')" \
find . -depth -execdir rename "${2:--n}" "s/${find_and_replace}" '{}' \;
)
使用连字符'-'替换空格''的示例用法。空运行:
find-rename-regex ' /-/g'
执行替换:
find-rename-regex ' /-/g' -v
与-execdir
不同,很棒的cd
选项在执行rename
命令之前将-exec
放入目录中。
-depth
确保重命名首先在孩子上进行,然后在父母上进行,以防止丢失父目录的潜在问题。
-execdir
是必需的,因为重命名在非基本名称的输入路径(例如,以下失败:
rename 's/findme/replaceme/g' acc/acc
需要进行PATH
黑客攻击,因为-execdir
有一个非常令人讨厌的缺点:find
极为自以为是,如果您有任何相对路径,则拒绝对-execdir
进行任何操作您的PATH
环境变量,例如./node_modules/.bin
,失败:
查找:相对路径“ ./node_modules/.bin”包含在PATH环境变量中,该变量与find的-execdir操作结合使用时不安全。请从$ PATH删除该条目
-execdir
是GNU查找extension to POSIX。 rename
基于Perl,来自rename
软件包。
重命名提前解决方法
如果您的输入路径不是来自find
,或者您已经受够了相对路径的烦恼,我们可以使用一些Perl预行来安全地重命名目录,如下所示:
git ls-files | sort -r | xargs rename 's/findme(?!.*\/)\/?$/replaceme/g' '{}'
我还没有找到-execdir
与xargs
的便捷类似物:https://superuser.com/questions/893890/xargs-change-working-directory-to-file-path-before-executing/915686
需要sort -r
来确保文件位于其各自的目录之后,因为较长的路径位于具有相同前缀的较短的路径之后。
在Ubuntu 18.10中进行了测试。
答案 6 :(得分:0)
如果您只想重命名并且不介意使用外部工具,则可以使用rnm。命令是:
#on current folder
rnm -dp -1 -fo -ssf '_dbg' -rs '/_dbg//' *
-dp -1
将使其递归到所有子目录。
-fo
表示仅文件模式。
-ssf '_dbg'
在文件名中搜索带有_dbg的文件。
-rs '/_dbg//'
用空字符串替换_dbg。
您也可以使用CURRENT_FOLDER的路径运行上述命令:
rnm -dp -1 -fo -ssf '_dbg' -rs '/_dbg//' /path/to/the/directory
答案 7 :(得分:0)
您可以在下方使用。
rename --no-act 's/\.html$/\.php/' *.html */*.html
答案 8 :(得分:-3)
经典解决方案:
var twitter_url = 'https://twitter.com/FameWaves_intl';
var facebook_url = 'https://facebook.com/famewaves';
var gplus_url = 'https://plus.google.com/famewaves';
$('ul.social li').each(function(){
var aLink = $(this).find('a'),
className = $(this).find('i').prop('class');
switch(className)
{
case "fa fa-twitter":
aLink.attr("href", twitter_url);
break;
case "fa fa-facebook":
aLink.attr("href", facebook_url);
break;
case "fa fa-google-plus":
aLink.attr("href", gplus_url);
break;
}
});