对于每个文件,.ext1
我都会生成第二个文件.ext2
,其文件名与扩展名相同,然后删除所有.ext1
文件。这个过程有时会失败,所以我想知道如何只删除.ext1
有对应文件的文件.ext2
。我想要这样的东西:
#!/bin/bash
ext1s=$(ls -l *.ext1 2>/dev/null | wc -l)
if [ $ext1s -ge 0 ]; then
generates .ext2 files
ext2s=$(ls -l *.ext2 2>/dev/null | wc -l)
if [ $ext1s -eq $ext2s ]; then
rm *.ext1
else
what i need
fi
else
echo no .ext1 files
exit
fi
答案1
只需迭代*.ext2
文件并删除匹配的.ext1
文件(如果存在)。
for f in *.ext2;do rm -f "$(basename "$f" .ext2).ext1";done
basename
不仅从完整路径中提取文件名,如果提供了第二个参数,它还将删除扩展名,因此"$(basename "$f" .ext2).ext1"
删除.ext2
扩展名并将其替换为.ext1
。
-f
如果文件不存在,则保持rm
沉默。.ext1
其无基本名称的版本是:
for f in *.ext2;do rm -f "${f%.ext2}.ext1";done
答案2
我找到了一个解决方案,如果有更好的方法,请分享。
#!/bin/bash
ext1s=$(ls -l *.ext1 2>/dev/null | wc -l)
if [ $ext1s -ge 0 ]; then
generates .ext2 files
ext2s=$(ls -l *.ext2 2>/dev/null | wc -l)
if [ $ext1s -eq $ext2s ]; then
rm *.ext1
else
list=$(comm -12 <(find *.ext1 -type f -exec bash -c 'basename "${0%.*}"' {} \; | sort) <(find *.ext2 -type f -exec bash -c 'basename "${0%.*}"' {} \; | sort))
for file in $list ; do
rm $file.ext1
done
fi
else
echo no .ext1 files
exit
fi
答案3
我不喜欢使用不必要的外部程序及其随之而来的开销:提问者的解决方案计划ls
(两次)、wc
(两次)、find
(两次)、comm
(bash
两次)、basename
(两次)和sort
(两次)。
这些都不是必需的:它们都可以由内部处理bash
:-
for f in *.ext1
do if [ "$f" == "*.ext1" ]
then echo no files
elif [ -e "${f%.ext1}.ext2" ]
then rm "$f"
else
# Insert here the code to create the .ext2 file from "$f"
fi
done
如果没有文件匹配*.ext1
,f
则将设置为该单个值;否则,将对每个匹配的文件进行循环遍历。(注意:如果您疯狂地创建了具有文字名称的文件*.ext1
,则“无文件”检查将失败。)
对于每个.ext1
文件,都会检查相应文件的存在.ext2
:如果存在,则.ext1
删除;否则,调用代码来创建文件.ext2
(可选,如果成功,则.ext1
可以删除原始文件,避免将来出现多余的.ext1
文件)。