LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - General
User Name
Password
Linux - General This Linux forum is for general Linux questions and discussion.
If it is Linux Related and doesn't seem to fit in any other forum then this is the place.

Notices


Reply
  Search this Thread
Old 03-23-2023, 05:24 PM   #1
lleb
Senior Member
 
Registered: Dec 2005
Location: Florida
Distribution: CentOS/Fedora/Pop!_OS
Posts: 2,983

Rep: Reputation: 551Reputation: 551Reputation: 551Reputation: 551Reputation: 551Reputation: 551
looping rsync to rename files at destination help?


Thank you for reading.

My goal is to take a large number of files from directory A into directory B, not always on the same server, using rsync and set a specific name at destination that is numbered.

Code:
#!/bin/bash

for i in *
do
	i=1
	rsync -aviS --progress *.avi /mnt/Exports/Backup/TEST/test.S01E0${i}
	i=i+1
done
The extension is not important, its just what im testing with atm.

the output that the above is generating is not what i desire:

1. it creates a new subdirectory under /mnt/Exports/Backup/TEST/ called test.S01E01
2. after creating the directory, that it should not be creating according to the rsync command, it is than moving the files from A to B/test.S01E01/, nothing is renamed in the process.

When I manually do this with:

Code:
rsync -aviS --progress foo\ \bad\ chars.avi /path/to/new/foo.no.bads.avi
it does exactly that into directory B as desired. This is time consuming and something that should be automated. I am horrid at coding, but thought a simple for loop should do the trick, my for loop is bad and wrong.

Looking for better guidance than RTFM or google as I've already spent far to much time RTFM and as not a programmer, not fully following examples, and my google foo fails as I dont know what to ask to get the correct output.

Thank you in advance for guidance, education, and direction.
 
Old 03-23-2023, 05:36 PM   #2
michaelk
Moderator
 
Registered: Aug 2002
Posts: 25,715

Rep: Reputation: 5899Reputation: 5899Reputation: 5899Reputation: 5899Reputation: 5899Reputation: 5899Reputation: 5899Reputation: 5899Reputation: 5899Reputation: 5899Reputation: 5899
Code:
for FILE in *.avi
do
  FILE_fixed=$(remove bad characters)
  rsync -aviS  "$FILE" /path/to/new/"$FILE_fixed"
done
Here is the basic loop... There are many ways to fix bad characters... Can you post an example?

Last edited by michaelk; 03-23-2023 at 05:45 PM.
 
1 members found this post helpful.
Old 03-23-2023, 06:05 PM   #3
lleb
Senior Member
 
Registered: Dec 2005
Location: Florida
Distribution: CentOS/Fedora/Pop!_OS
Posts: 2,983

Original Poster
Rep: Reputation: 551Reputation: 551Reputation: 551Reputation: 551Reputation: 551Reputation: 551
michaelk,

I have either ran a bit more complicated code that a friend made for me, i will post that in a bit, or just the manual rsync command above. What I want to avoid is renaming the files before the rsync command, source files in directory A need to stay are they are named.

rename code
Code:
#!/bin/bash

# loop to scan entire directory for all file extension
# remove original file name and number 0001.ext - XXXX.ext
# using BASH 4.0 or greater should be able to use 'tr' to convert from
# uppercase to lowercase letters in the file
# Code from friend <25 July, 2021>
# NOTE: this will also move directories to lowercase and NN.####.foo
# ex:  Old/  will move to NN.####.old/

###########################################################################
N=1
for OLDNAME in *	# OLDNAME is the original name of the file
do
    # convert from upper to lower case
    LOWER="$( echo "${OLDNAME}" | tr '[:upper:]' '[:lower:]')"
    # EXT is file extension to be left in place
    EXT="${LOWER##*.}"
    # check if file has an extension, if not do nothing and move on
    if [[ -n "$EXT" ]]
    then
        EXT=".$EXT"
    fi
    # NEWNAME will be 2 padded 0's with original file type 0001.ext  
    NEWNAME="$( printf '%02d%s' $N "$EXT" )"
    #NEWNAME="$( printf '%04d.%s' $N "$EXT" )"
    # if loop to check that the original file name is not already 0001.ext
    # if not !=, than perform the mv function to 0001.ext
    if [[ "${OLDNAME}" != "${NEWNAME}" ]]
    then
        mv -v -- "${OLDNAME}" "${NEWNAME}"
    fi
    N=$((N+1))
	
done
###########################################################################

# Code updated with help from friend <July 25, 2021>
# convert webp to jpg and remove original file if not error using &&
# must have ffmpeg installed on system for these lines to work
for x in ls *.webp; do
	ffmpeg -loglevel panic -i "$x" "${x%.webp}".jpg && rm "$x"
done

# convert webm to mkv and remove original file if not error using &&
for x in ls *.webm; do
	ffmpeg -loglevel panic -i "$x" "${x%.webm}".mkv && rm "$x"
done
###########################################################################
# with new information from above code provided by friend
# removed multiple loops and replaced with single loop below
# me July 25, 2021

# prepend file XXXX.ext with NN.
# replace NN. with correct file name
for f in *
do
    mv "$f" "NN$f" 
done
###########################################################################

# move *.sh back to Numbers.sh and *.txt to grab.txt
# NOTE: make sure only 1 each .txt and .sh file in the directory or this
#       will fail
mv *.sh Numbers.sh
# mv *.txt grab.txt
###########################################################################
This is a much bigger hammer than I want to take to the files in directory A. Currently I will rsync *.(extension type) /path/to/destination/ than i will modify the above script to rename and number everything in directory B.

When the number of files to move is limited I will do so as the way I typed in the OP. Thus my desire to use a for loop with rsync to move the files. That should, in theory, both clean up the files in A as well as provide the desired output and ordered numbering in B.
 
Old 03-23-2023, 06:20 PM   #4
michaelk
Moderator
 
Registered: Aug 2002
Posts: 25,715

Rep: Reputation: 5899Reputation: 5899Reputation: 5899Reputation: 5899Reputation: 5899Reputation: 5899Reputation: 5899Reputation: 5899Reputation: 5899Reputation: 5899Reputation: 5899
If that rename section of code still works for you then just replace the mv with rsync. Pull that one section of code to a new script if I understand what you are trying to accomplish.
Code:
    if [[ "${OLDNAME}" != "${NEWNAME}" ]]
    then
        mv -v -- "${OLDNAME}" "${NEWNAME}"
    fi
Replace with
Code:
rsync ... "${OLDNAME}" /path/to/new/"${NEWNAME}"
 
1 members found this post helpful.
Old 03-23-2023, 06:55 PM   #5
lleb
Senior Member
 
Registered: Dec 2005
Location: Florida
Distribution: CentOS/Fedora/Pop!_OS
Posts: 2,983

Original Poster
Rep: Reputation: 551Reputation: 551Reputation: 551Reputation: 551Reputation: 551Reputation: 551
that seems to be renaming before it moves the files to B. I am sending from A to B if that matters.

I have this 99.96% working

Code:
#!/bin/bash

###########################################################################
N=1
for OLDNAME in *	# OLDNAME is the original name of the file
do
    # convert from upper to lower case
    LOWER="$( echo "${OLDNAME}" | tr '[:upper:]' '[:lower:]')"
    # EXT is file extension to be left in place
    EXT="${LOWER##*.}"
    # check if file has an extension, if not do nothing and move on
    if [[ -n "$EXT" ]]
    then
        EXT=".$EXT"
    fi
    # NEWNAME will be 2 padded 0's with original file type 0001.ext  
    NEWNAME="$( printf '%02d%s' $N "$EXT" )"
    SNEWNAME=Name."${NEWNAME}"
    
    if [[ "${OLDNAME}" != "${NEWNAME}" ]]
    then
    	rsync -aviS --progress "${OLDNAME}" /path/to/foo/"${SNEWNAME}"
    fi
    N=$((N+1))
done
question, so from what i understand reading this code, if a file has no extension it should be ignored. when i ran this script it moved a file without an extension to B directory? why? What did I goof?

FYI, you rock michaelk.
 
Old 03-23-2023, 07:26 PM   #6
michaelk
Moderator
 
Registered: Aug 2002
Posts: 25,715

Rep: Reputation: 5899Reputation: 5899Reputation: 5899Reputation: 5899Reputation: 5899Reputation: 5899Reputation: 5899Reputation: 5899Reputation: 5899Reputation: 5899Reputation: 5899
Code:
#!/bin/bash

###########################################################################
N=1
for OLDNAME in *	# OLDNAME is the original name of the file
do
    # convert from upper to lower case
    LOWER="$( echo "${OLDNAME}" | tr '[:upper:]' '[:lower:]')"
    # EXT is file extension to be left in place
    EXT="${LOWER##*.}"
    # check if file has an extension, if not do nothing and move on
    if [[ -n "$EXT" ]]
    then
        EXT=".$EXT"
    else
        # no extension go to next file
        continue
    fi
    # NEWNAME will be 2 padded 0's with original file type 0001.ext  
    NEWNAME="$( printf '%02d%s' $N "$EXT" )"
    SNEWNAME=Name."${NEWNAME}"
    
    rsync -aviS --progress "${OLDNAME}" /path/to/foo/"${SNEWNAME}"

    N=$((N+1))
done
I don't think you need the if oldname = newname but if it does not work as desired you can always add it back in. If no extension I added an else which executes a continue. That basically skips the rest of the code in the loop and therefore the file is not copied.

I consider myself a novice programmer despite my experience...

Last edited by michaelk; 03-23-2023 at 07:27 PM.
 
1 members found this post helpful.
Old 03-23-2023, 08:04 PM   #7
lleb
Senior Member
 
Registered: Dec 2005
Location: Florida
Distribution: CentOS/Fedora/Pop!_OS
Posts: 2,983

Original Poster
Rep: Reputation: 551Reputation: 551Reputation: 551Reputation: 551Reputation: 551Reputation: 551
hmm, seems better. It is still moving to script over as NEWNAME.z and for some odd reason the rm command is not removing said file from B

Code:
#!/bin/bash
PATH=foo
###########################################################################
N=1
for OLDNAME in *        # OLDNAME is the original name of the file
do
    # convert from upper to lower case
    LOWER="$( echo "${OLDNAME}" | /usr/bin/tr '[:upper:]' '[:lower:]')"
    # EXT is file extension to be left in place
    EXT="${LOWER##*.}"
    # check if file has an extension, if not do nothing and move on
    if [[ -n "$EXT" ]]
    then
        EXT=".$EXT"
    else
        # contineu if no extension for file
        continue
    fi
    # NEWNAME will be 2 padded 0's with original file type 0001.ext
    NEWNAME="$( printf '%02d%s' $N "$EXT" )"
    SNEWNAME=Name"${NEWNAME}"

    if [[ "${OLDNAME}" != "${NEWNAME}" ]]
    then
        /usr/local/bin/rsync -aviS --progress "${OLDNAME}" $PATH"${SNEWNAME}"
    fi
    N=$((N+1))
done
##########################################################################
/usr/rm ${PATH}*.z
Also for whatever reason after adding that slight change of continue the system demanded full pathing. should have done that from the start i suppose.
 
Old 03-23-2023, 10:24 PM   #8
michaelk
Moderator
 
Registered: Aug 2002
Posts: 25,715

Rep: Reputation: 5899Reputation: 5899Reputation: 5899Reputation: 5899Reputation: 5899Reputation: 5899Reputation: 5899Reputation: 5899Reputation: 5899Reputation: 5899Reputation: 5899
Quote:
rsync -aviS --progress foo\ \bad\ chars.avi /path/to/new/foo.no.bads.avi
What do you want the new file name format to look like?
 
Old 03-24-2023, 07:24 AM   #9
lleb
Senior Member
 
Registered: Dec 2005
Location: Florida
Distribution: CentOS/Fedora/Pop!_OS
Posts: 2,983

Original Poster
Rep: Reputation: 551Reputation: 551Reputation: 551Reputation: 551Reputation: 551Reputation: 551
Quote:
Originally Posted by michaelk View Post
What do you want the new file name format to look like?
Sorry for the delay in reply. The output of the new script is working for the most part. Only parts not working are:

1. it is moving a copy of the script over that i have named 'z' no extension
2. even with the script portion that is supposed to ignore files without extensions it is still touching all files
3. knowing that, the last line should clean up the mess and it is not.

a clean format will be a name without special characters or spaces, numbered in order, with the same extension as the original file.
 
Old 03-24-2023, 08:58 AM   #10
michaelk
Moderator
 
Registered: Aug 2002
Posts: 25,715

Rep: Reputation: 5899Reputation: 5899Reputation: 5899Reputation: 5899Reputation: 5899Reputation: 5899Reputation: 5899Reputation: 5899Reputation: 5899Reputation: 5899Reputation: 5899
Code:
    # replace spaces with underscore
    OLDNAME="${OLDNAME// /_}"
    remove non printable characters and convert to lowercase
    LOWER=$( echo "${OLDNAME}" | tr -dc '[:print:]' | tr -dc [:alpha:]_. | tr '[:upper:]' '[:lower:]')
    # EXT is file extension to be left in place
    EXT="${LOWER##*.}"
    # strip base name
    base="${LOWER%%.*}"
    # check if file has an extension, if not do nothing and move on
    if [[ ! "$LOWER" == "$EXT" ]]
    then
        EXT=".$EXT"
        echo "ext=$EXT"
    else
        continue
    fi
    
    NEWNAME="$( printf '%s%02d%s' $base $N "$EXT" )"
 
    echo "$NEWNAME"
Not sure how you want to "string" the new name together.

Last edited by michaelk; 03-24-2023 at 09:02 AM.
 
1 members found this post helpful.
Old 03-28-2023, 08:46 AM   #11
MadeInGermany
Senior Member
 
Registered: Dec 2011
Location: Simplicity
Posts: 2,798

Rep: Reputation: 1201Reputation: 1201Reputation: 1201Reputation: 1201Reputation: 1201Reputation: 1201Reputation: 1201Reputation: 1201Reputation: 1201
There is a bug in
Code:
    EXT="${LOWER##*.}"
    # check if file has an extension, if not do nothing and move on
    if [[ -n "$EXT" ]]
$EXT becomes $LOWER if there is no match (no dot)!
The fix was already in the previous post.
Code:
    EXT="${LOWER##*.}"
    # check if file has an extension, if not do nothing and move on
    if [[ "$LOWER" != "$EXT" ]]
BTW shouldn't both EXT,base variables take the rightmost dot? Then it must be
Code:
    EXT="${LOWER##*.}" # Maximum match from the left
    # strip base name
    base="${LOWER%.*}" # Minimum match from the right

Last edited by MadeInGermany; 03-28-2023 at 09:29 AM.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
LXer: How to Bulk Rename Files in Linux with Thunar’s Bulk Rename Tool LXer Syndicated Linux News 0 11-27-2019 07:03 PM
LXer: GUI To Batch Rename Files On Linux With Exif And Music Tags Support: Inviska Rename LXer Syndicated Linux News 0 05-25-2019 12:07 PM
[SOLVED] Bash Scripting: rename bunches of files using source/destination list bits45 Programming 7 08-17-2015 02:43 PM
[SOLVED] match source pattern in destination and substitute in destination usin AWK 123raajesh Linux - Software 7 11-13-2013 04:22 AM
destination unavailable W/ vpn. All other net destination o.k. MikeOfAustin Linux - Networking 1 04-07-2007 04:42 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - General

All times are GMT -5. The time now is 11:28 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration