我有许多标题为“20150512_101129_3016”的目录,以及其他带有附加下划线的附加字符串的目录,例如“20150512_101129_3016_v1A”(它并不总是 v1A,可能是 v1 或 V1a 等)。我想重命名所有目录,以便删除最后一个下划线后面的最后一个字符串。我更喜欢一种解决方案,该解决方案能够删除最后一个/第三个下划线之后(并包括)之后的所有文本,因为我不确定所有目录名称在第三个下划线之前的文本中将具有相同数量的字符。
答案1
您可以使用简单的 shell 循环来完成此操作:
for x in ./*_*_*_*; do mv -i "$x" "${x%_*}"; done
即对于名称至少包含三个下划线的每个文件,重命名该文件,删除从最后一个下划线开始的部分。
如果存在冲突(例如,两者20150512_101129_3016_v1A
都20150512_101129_3016_v1B
存在),则按字典顺序的第一个文件将被重命名为所需的目标,第二个文件将被移动到子目录,即20150512_101129_3016_v1B
在20150512_101129_3016/20150512_101129_3016_v1B
重20150512_101129_3016_v1A
命名为20150512_101129_3016
.为了避免这种情况,请添加额外的检查:
for x in ./*_*_*_*; do
if [ -e "${x%_*}" ]; then
echo "Not renaming $x because ${x%_*} already exists"
continue
fi
mv "$x" "${x%_*}"
done
或者,在 Linux 上,将-T
选项传递给mv
使其执行此检查。
答案2
如果原始目录名称是同质的,即遵循 XXXXX_XXXX_XXXX 的格式(然后可能后面跟着另一个 _ XXXX),下面的代码段应该可以工作:
find ./ -maxdepth 1 -type d | while read dir; do
newdir=$(echo ${dir} | cut -d_ -f1-3)
# duplicate directory name protection
if [ -d ${newdir} ]
then
newdir=${newdir}_
echo "duplicate directory encountered. Appending _ to the new dir name"
fi
#did the dir name change ? If not, do nothing
if [ ${newdir} != ${dir} ]
then
mv ${dir} ${newdir}
fi
done
它假设您位于包含这些子目录的目录中。