5

I have 2 folders one contains images files and the second contains text files each text file have the same name as the image file and contains information about the image.eg:

   -Labels:
     -1.txt
     -2.txt
     -3.txt
     -6.txt
   -Images:
     -1.jpg
     -2.jpg
     -3.jpg
     -4.jpg
     -5.jpg
     -6.jpg

I want to delete images who has not a text file(in this example:4.jpg,5.jpg), I found a method how to determinate the different files but I can't delete them.

diff <(ls -1 ./Images | sed s/.jpg//g) <( ls -1 ./Labels | sed s/.txt//g)

3 Answers 3

8

Here is a small bash script that can help you to solve this task:

#!/bin/bash
for file in Images/*.jpg
do
    if [[ ! -f "Labels/$(basename ${file%.*}).txt" ]]
    then
        echo rm "$file"
    fi
done
  • Remove echo to do the actual changes.

The script must be executed in the parent directory, here it is formatted as inline command:

for f in Images/*.jpg; do if [[ ! -f "Labels/$(basename ${f%.*}).txt" ]]; then echo rm "$f"; fi; done
2
  • I am way too fond of sed, your solution is more elegant, thanks!
    – Dries
    Aug 2, 2019 at 16:15
  • In zsh you can use ${file:r} instead of ${file%.*} to get the filename minus one extension. It's smarter about what that means, which can be an advantage over substring matches when you're dealing with mixed paths that don't all fit a simple pattern. (e.g. file="foo.bar/baz"; echo ${file:r} will return foo.bar/baz, not foo. Though file="foo.bar/.baz" will produce foo.bar/ by either method, so some care is still required.)
    – FeRD
    Aug 3, 2019 at 3:06
6

I think I would do it like this:

for i in Images/*; do file=`echo $i | sed -e 's/jpg/txt/' -e 's/Images/Labels/'`; if [ ! -f "$file" ] ; then rm $i ; fi; done

If you want to make sure it works , before actually using it try this first:

for i in Images/*; do file=`echo $i | sed -e 's/jpg/txt/' -e 's/Images/Labels/'`; if [ ! -f "$file" ] ; then echo rm $i ; fi; done

It will show which commands will be executed.

3
cd /path/to/Images
LIST=$(find /path/to/Labels -iname *.txt -printf "%f|" | sed 's/.txt/.jpg/g')
rm -i !($LIST)
  1. Generates a list of txt files.
  2. Changes their extension to jpg.
  3. Removes anything that is not on the list.

    • -i is just for safety.
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .