删除XML个没有对应JPG文件的文件

Delete XML file which does not have corresponding JPG file

我有一个文件夹,其中包含图像和 XML 个同名文件

举个例子

A.jpg A.xml
B.jpg B.xml
C.jpg C.xml

等等

我想删除 XML 个没有相应 jpg 文件的文件

所有文件都在同一个文件夹中。

OS - Ubuntu 16.04 LTS

与 bash 及其 Parameter Expansion:

for file in *.xml; do
  jpg="${file%.xml*}.jpg"      # if $file contains A.xml, $jpg is set with A.jpg 
  if [[ ! -e "$jpg" ]]; then   # true if $jpg does not exists
    echo rm -v "$file"
  fi
done

如果输出看起来不错,请删除 echo

这个python代码可以提供帮助,您只需要编辑路径变量。

import os
from tqdm import tqdm

path = 'your path'

files = os.listdir(path)

for file in tqdm(files):
    filename, filetype = file.split('.')
    if filetype == 'xml':
        continue

    imgfile = os.path.join(path, file)
    xmlfile = os.path.join(path, filename + '.xml')
    if not os.path.exists(xmlfile):
        print('{} deleted.'.format(imgfile))
        os.remove(imgfile)

从技术上讲,无论使用命令行还是任何脚本语言,您都可以通过这种方式解决问题

首先找到并分离 xml 文件和 jpg

的列表
find -name \*.xml | sed 's/\.xml//g' > list-xml
find -name \*.jpg | sed 's/\.jpg//g' > list-jpg

我们不关心文件扩展名:xmljpg 只关心文件名

第二次对两个列表进行排序并使它们唯一,那些 1 是单个文件,没有相应的 xmljpg

cat list-xml list-jpg | sort | uniq -c | grep 1

第三次检查输出

这是一个没有 xmljpg 的文件名,如果它是 xml 我们应该删除它


即使是递归的例子

tree .
├── one
│   ├── A.jpg
│   ├── A.xml
│   ├── B.jpg
│   ├── B.xml
│   ├── C.jpg
│   ├── C.xml
│   └── D.xml      # this one is a single one
├── three
│   ├── A.jpg
│   ├── A.xml
│   ├── B.jpg
│   ├── B.xml
│   ├── C.jpg
│   └── C.xml
└── two
    ├── A.jpg
    ├── A.xml
    ├── B.jpg
    ├── B.xml
    ├── C.jpg
    └── C.xml

现在我们的输出是:

cat list-xml list-jpg | sort | uniq -c | grep 1
      1 ./one/D

我们知道我们应该删除这个文件 如果它是一个 xml 文件。如此简单尝试

rm -f ./one/D.xml

多于一个文件如何?

嗯。存储输出列表;在 all 末尾添加 xml ,然后删除列表中的所有文件。像这样,如果您将输出存储在名为 result

的文件中
perl -lne 's/ +\d//g && print "$_.xml"' result

这给你:

./one/D.xml

您可以使用 perl 直接删除它们,或者最好将它们存储起来,这样您就可以拥有一个列表,列出您拥有/想要删除的内容。


你也可以很简单地解决它,但有点棘手。 仔细考虑您的需求:

I want to delete XML files which do not have their corresponding jpg files

因此您需要删除 xml 个文件,因为我们没有同名但格式为 jpg 的文件,对吗?

所有 xml 个文件的第一个列表

find -name \*.xml > all-xml

检查文件是否存在但格式为jpg

$ perl -lne 's/\.xml$/.jpg/g && print -e  $_' all-xml 
1
1
1
1
1
         # this file does not exist
1
1
1
1
$ # it means that xml file exists but it has no corresponding jpg file
$ # we can see name of this file
$ # here with perl we see if it exists -e $_ do nothing
$ # otherwise print the file
$ perl -lne 's/\.xml$/.jpg/g && -e  $_ || s/\.jpg/\.xml/ && print ' all-xml
./one/D.xml

没有相应 jpg 的文件是:

./one/D.xml

你可以像这样在一行中完成:

perl -MFile::Find -le 'find(sub{ ($_=$File::Find::name) && push(@xml,$_) }, "." ); END{ s/xml$/jpg/ && print -e $_ || (s/jpg$/xml/) &&  print $_ for @xml}'
1
./all-xml           # ./all.jpg does not exist, yes it is our file
1
1
1
1
1
1
1
./one/D.xml         # ./one/D.jpg does not exist so this file should be deleted 
1
1
1
1
1

此代码将删除所有没有相应 .xml 文件的 .jpg 文件和所有没有相应 .jpg 文件的 .xml 文件

   import os

files = os.listdir("training")
for i in files:
    for j in os.listdir("training/"+i):
        if (j.split(".")[0] + ".xml" not in os.listdir("training/"+i)) or (j.split(".")[0] + ".jpg" not in os.listdir("training/"+i)) :
        
            print(j)
            os.remove("training/"+i+"/"+j)