我正在开发一个shell脚本,现在我需要通过删除此模式并将它们移动到特定文件夹来重命名以数字和空白开头的文件这基本上是第二个和第三个“ - ”之间的字符串
example :
001 - folder1 - example.doc > /folder1/example.doc
002 - folder2 - someexample.doc > /folder2/someexample.doc
003 - folder3 - someotherexample.doc > /folder3/someotherexample.doc
我想做一些像
这样的事情find /tmp -name '*.doc' -print | rename .... ...
我不知道的是:
- 如何告诉发现文件以数字开头,
和第二个
- 如何通过“ - ”之类的模式来爆炸名称,并告诉重命名将文件放在文件夹中
答案 0 :(得分:4)
如果可能的话,我会避免find
,只使用bash
的正则表达式匹配。如果您不需要递归搜索/tmp
(正如您的find
版本所做的那样),这应该适用于任何版本的bash
:
regex='^[[:digit:]]+ - (.+) - (.+)$'
for f in /tmp/*.doc; do
[[ $f =~ /tmp/$regex ]] || continue
mv -- "$f" "/${BASH_REMATCH[1]/${BASH_REMATCH[2]}"
done
如果 需要递归搜索,并且您使用的是bash
4或更高版本,则可以使用globstar
选项:
shopt -s globstar
regex='^[[:digit:]]+ - (.+) - (.+)$'
for f in /tmp/**/*.doc; do
b=$(basename "$f")
[[ $b =~ $regex ]] || continue
mv -- "$f" "/${BASH_REMATCH[1]/${BASH_REMATCH[2]}"
done
答案 1 :(得分:1)
如果您的目标文件夹和文件名没有空格,并且所有原始文件都在当前目录中,您可以尝试以下操作:
while read f; do
if [[ "$f" =~ ^\./[0-9]+\ -\ ([^\ ]+)\ -\ (.+\.doc)$ ]]; then
mkdir -p "${BASH_REMATCH[1]}"
mv "$f" "${BASH_REMATCH[1]}/${BASH_REMATCH[2]}"
fi
done < <(find . -maxdepth 1 -name '[0-9]*.doc')
<强>说明强>:
find . -maxdepth 1...
将搜索限制在当前目录中。find...-name '[0-9]*.doc
仅匹配名称以至少一位开头且以.doc
结尾的文件。./
添加的初始find
。它包含两个子句,包含在(...)
中,对应于文件夹名称和目标文件名。如果存在匹配,则这些子表达式将由bash存储在BASH_REMATCH
数组中,分别位于第1和第2位。答案 2 :(得分:1)
gawk:
find . -regex '^.*[0-9]+ - [a-zA-Z]+[0-9] - [a-zA-Z]+\.doc$' -printf %f | awk -F- '{ print "mv \""$0"\" /"gensub(" ","","g",$2)"/"gensub(" ","","g",$3) }'
将find与正则表达式一起使用,然后将输出解析为awk以执行move命令。
验证命令正常后,运行命令。
find . -regex '^.*[0-9]+ - [a-zA-Z]+[0-9] - [a-zA-Z]+\.doc$' -printf %f | awk -F- '{ print "mv \""$0"\" /"gensub(" ","","g",$2)"/"gensub(" ","","g",$3) }' | sh
要小心这种策略可能会面临命令注入的风险。
答案 3 :(得分:0)
答案非常接近Raman的建议,我删除了printf,添加了创建文件夹的部分,并添加了删除前导和尾随空白的部分。
最后它看起来像这样:
find . -regex '^.*[0-9].*\.doc$' | awk -F- '{ print "mkdir \""gensub(" $","","g",gensub("^ ","","g",$2))"\" \nmv \""$f"\" \"./"gensub(" $","","g",gensub("^ ","","g",$2))"/"gensub(" $","","g",gensub("^ ","","g",$2"-"$3))"\"" }'|sh
谢谢大家的建议。