如何比较两个文件名相同(扩展名除外)的文件列表,删除仅匹配 shell 脚本

如何比较两个文件名相同(扩展名除外)的文件列表,删除仅匹配 shell 脚本

对于每个文件,.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(两次)、commbash两次)、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

如果没有文件匹配*.ext1f则将设置为该单个值;否则,将对每个匹配的文件进行循环遍历。(注意:如果您疯狂地创建了具有文字名称的文件*.ext1,则“无文件”检查将失败。)

对于每个.ext1文件,都会检查相应文件的存在.ext2:如果存在,则.ext1删除;否则,调用代码来创建文件.ext2(可选,如果成功,则.ext1可以删除原始文件,避免将来出现多余的.ext1文件)。

相关内容