我有几个目录,例如:
"Some NameAndMorEyy_mm_dd"
,我想将它们重命名为:
"yy_mm_dd_Some NameAndMore"
Some NameAndMore
部分可以包含重音符号,空格,并且可以以空格或_
或两者兼有,并且需要将其删除。
一些例子:
"Jhon Doe_18_08_02"
"Jhon Doe 18_08_03"
"Jhon Doe_ 18_08_04"
"Jhon Doe _18_07_02"
"Jhon Doé_18_10_02"
"Jhon Doñe_18_08_02"
应重命名为:
"18_08_02_Jhon Doe"
"18_08_03_Jhon Doe"
"18_08_04_Jhon Doe"
"18_07_02_Jhon Doe"
"18_10_02_Jhon Doé"
"18_08_02_Jhon Doñe"
分别。
现在,以and空格和_
结尾的仅是少数几个,因此您可以根据需要忽略它们。
答案 0 :(得分:2)
这(mv
除外)是纯Bash解决方案:
#! /bin/bash
shopt -s dotglob # Globs match names beginning with '.'
shopt -s nullglob # Globs expand to nothing when nothing matches
for namedate in *[0-9][0-9]_[0-9][0-9]_[0-9][0-9] ; do
[[ -d $namedate ]] || continue # Skip non-directories
name=${namedate%??_??_??} # Remove date from end to get name
date=${namedate#"$name"} # Remove name from start to get date
name=${name%[ _]} # Remove trailing space or _
name=${name%[ _]} # Remove possible 2nd trailing space or _
datename=${date}_${name}
if [[ -e $datename ]] ; then
printf "Warning: '%s' already exists. Skipping.\\n" "$datename" >&2
else
mv -- "$namedate" "$datename"
printf "Moved '%s' to '%s'\\n" "$namedate" "$datename" >&2
fi
done
代码是Shellcheck干净的。为了避免做奇怪的事情,它会在执行mv
之前检查目标目录是否不存在。
答案 1 :(得分:1)
这是一个较慢的解决方案,但它应该可以工作。用实际的移动命令替换echo "move ..."
。可以使用较少的sed
子外壳来加快速度。
想法是通过查找数字的开头来找到拆分。假设名称中没有数字。我们分为两部分,删除名称中的_或空格,然后在移动中重新组合在一起。
还使用find
,以便可以正确处理带有空格的文件。
#!/bin/bash
find . -mindepth 1 -maxdepth 1 -type d | (while read -r d; do
d=$(basename "$d")
name_part=$(echo "$d" | sed -rn 's/(^[^0-9]+)(.*)$/\1/p')
date_part=$(echo "$d" | sed -rn 's/(^[^0-9]+)(.*)$/\2/p')
name_part=$(echo "$name_part" | sed -rn 's/([_ ]+)$//p')
# change this line here
# mv "$d" "${date_part}_${name_part}"
echo "move $d ==> ${date_part}_${name_part}"
done)
从测试数据中,输出显示:
move Jhon Doe_18_08_02 ==> 18_08_02_Jhon Doe
move Jhon Doe 18_08_03 ==> 18_08_03_Jhon Doe
move Jhon Doe_ 18_08_04 ==> 18_08_04_Jhon Doe
move Jhon Doñe_18_08_02 ==> 18_08_02_Jhon Doñe
move Jhon Doé_18_10_02 ==> 18_10_02_Jhon Doé
答案 2 :(得分:1)
还有一个懒惰的衬里:) ...剥离第一个回波以使其起作用。
for i in *; do [[ -d $i ]] && echo mv "$i" "$( echo $i| sed -r -e 's/^(.+)([0-9][0-9]_[0-9][0-9]_[0-9][0-9])$/\2_\1/' -e 's/[_ ]+$//' )" ; done
mv Jhon Doe _18_07_02 18_07_02_Jhon Doe
mv Jhon Doe_18_08_02 18_08_02_Jhon Doe
mv Jhon Doe 18_08_03 18_08_03_Jhon Doe
mv Jhon Doe_ 18_08_04 18_08_04_Jhon Doe
mv Jhon Doé_18_10_02 18_10_02_Jhon Doé
mv Jhon Doñe_18_08_02 18_08_02_Jhon Doñ