how to recursively remove files from one folder if its file name doesn't appear in another folder

Solution 1:

Here's one way:

$ for file in folder_1/*.jpg; do 
    fileName="${file##*/}"
    [[ -e folder_2/${fileName/.txt/.jpg} ]] || echo rm -- "$file"
done
rm -- folder_1/03.txt
rm -- folder_1/04.txt

The for loop iterates over all non-hidden files and directories in folder_1 whose name ends in .jpg, saving each as $file. Next, fileName="${file##*/}" sets the variable $fileName to the value of $file with everything until the last / removed, which means it will be the file's name without the directory. Finally, with [[ -e folder_2/${fileName/.txt/.jpg} ]] || echo rm -- $file, we check if there is a file in folder_2 with the same name but a .txt extension and, if not, echo rm -- "$file". If this does what you want, remove the echo and run again to actually delete the files:

for file in folder_1/*.jpg; do 
    fileName="${file##*/}"
    [[ -e folder_2/${fileName/.txt/.jpg} ]] || rm -- "$file"
done

The -- in rm -- "$file" isn't necessary here but is a good habit to have: it ensures that anything after the -- is not parsed as an option to rm, therefore allowing the command to also work on file names starting with an -.