this post was submitted on 06 Dec 2025
50 points (100.0% liked)

Linux

60104 readers
1047 users here now

From Wikipedia, the free encyclopedia

Linux is a family of open source Unix-like operating systems based on the Linux kernel, an operating system kernel first released on September 17, 1991 by Linus Torvalds. Linux is typically packaged in a Linux distribution (or distro for short).

Distributions include the Linux kernel and supporting system software and libraries, many of which are provided by the GNU Project. Many Linux distributions use the word "Linux" in their name, but the Free Software Foundation uses the name GNU/Linux to emphasize the importance of GNU software, causing some controversy.

Rules

Related Communities

Community icon by Alpár-Etele Méder, licensed under CC BY 3.0

founded 6 years ago
MODERATORS
 

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

you are viewing a single comment's thread
view the rest of the comments
[–] Rentlar@lemmy.ca 4 points 4 days ago* (last edited 4 days ago) (1 children)

Edit: I think there are better answers downthread than mine, but I hope my first comment spurned them on.

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 3 points 4 days ago* (last edited 4 days 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