Hello everyone,

Hoping that this is a good place to post a question about Bash scripting. My wife and I have run into a problem in PhotoPrism where it keeps tagging pictures and videos with similar names together and so the thumbnail and the video do not match. I decided that rather than try to get her iPhone to tweak its naming it’s easier to just offload to a directory then rename every file to a UUID before sending to photoprism. I’m trying to write a bash script to simplify this but cannot get the internal loop to fire. The issue appears to be with the ‘while IFS= read -r -d ‘’ file; do’ portion. Is anyone able to spot what the issue may be?

#! /bin/bash
echo "This script will rename all files in this directory with unique names. Continue? (Y/N)"
read proceed
if [[ "$proceed" == "Y" ]]; then
	echo "Proceed"
	#use uuidgen -r to generate a random UUID.
	#Currently appears to be skipping the loop entirely. the find command works so issue should be after the pipe.
	   
# Troubleshooting
#Seems like changing IFS to $IFS helped. Now however it's also pulling others., don't think this is correct.
#verified that the find statement is correct, its the parsing afterwards that's wrong.
#tried removing the $'\0' after -d as that is string null in c. went to bash friendly '' based on https://stackoverflow.com/questions/57497365/what-does-the-bash-read-d-do
#issue definitely appears to be with the while statement
	find ./ -type f \( -iname \*.jpg -o -iname \*.png \) | while IFS= read -r -d '' file; do
	   echo "in loop"
	   echo "$file"
	   #useful post https://itsfoss.gitlab.io/post/how-to-find-and-rename-files-in-linux/
	   #extract the directory and filename
	   dir=$(dirname "$file")
	   base=$(basename "$file")
	   echo "'$dir'/'$base'"
	   #use UUID's to get around photoprism poor handling of matching file names and apples high collision rate
	   new_name="$dir/$(uuidgen -r)"
	   echo "Renaming ${file} to ${new_name}"
	   #mv "$file" "$new_name" #uncomment to actually perform the rename.
	done
	echo "After loop"
else
	echo "Cancelling"
fi

  • Rentlar@lemmy.ca
    link
    fedilink
    arrow-up
    4
    ·
    5 hours ago

    Not the most experienced bash guru at it but let me see…

    • does the while condition have to be within [ ] brackets?
    • Also I can’t figure out what your condition is, it seems to have an unclosed quotation mark.
    • Most bash while-do-done loops I’ve made have a comparator like -ne for not equal or -le for less or equal to. So for example: while [ $variable -ne 5 ]; do
    • FigMcLargeHuge@sh.itjust.works
      link
      fedilink
      English
      arrow-up
      2
      ·
      edit-2
      4 hours ago

      Also, I am not sure you can automatically expect the output of the find command to be assigned to the file variable. I would output the find command to a temp file, and then grab the filenames one by one from the file and then put that in a do/done loop. Eg:

      find ./ -type f \( -iname \*.jpg -o -iname \*.png \) > yourtempfile.tmp    
      for file in `cat yourtempfile.tmp`     
      do     
          echo "in loop"    
          echo "$file"    
      ....     
      done
      

      Here are some results I got when it ran:

      in loop
      ./Figs_XSR900.JPG
      ‘.’/‘Figs_XSR900.JPG’
      Renaming ./Figs_XSR900.JPG to ./356bb549-d25c-4c9b-a441-f8175f963c8c
      in loop
      ./20240625195740_411A6199.JPG
      ‘.’/‘20240625195740_411A6199.JPG’
      Renaming ./20240625195740_411A6199.JPG to ./3cc9ba51-1d15-4a10-b9ee-420a5666e3e2