why are you using ls with an extra process to while loop? Just use a for loop with shell expansion. This is preferred way

#!/bin/bash
shopt -s nullglob
for file in *
do
  if [ -f "$file" ];then
    newfile="${file##* }"
    mv "$file" $newfile"
  fi
done
Answer from ghostdog74 on Stack Overflow
Discussions

Copy and rename file from shell script
It's hard to tell because the formatting is real messed up You can rename with just: cp /path/to/source/file /path/to/destination/newname More on reddit.com
🌐 r/bash
28
2
October 26, 2023
bash - Rename all files in directory from $filename_h to $filename_half? - Stack Overflow
@Ryan @Ishan Jain In fact it indicates the backend shell that must execute the script. sh and bash are different shells so it may affect the script behavior and syntax. Since the script uses a bash built-in string replacement you should add the header #!/bin/bash. More on stackoverflow.com
🌐 stackoverflow.com
shell script - rename files with rename command - Unix & Linux Stack Exchange
Please advice what is wrong with the following command find /tmp/dir -name "* *" -type f | rename 's/*/fixed_/g' remark - I prefer to do that with one command not loop syntax What I want is to re... More on unix.stackexchange.com
🌐 unix.stackexchange.com
September 3, 2014
linux - How to rename multiple files in single command or script in Unix? - Unix & Linux Stack Exchange
Strangely, the -i option doesn't prompt for y/n before renaming files on the Redhat system I am on. Anyone know why? ... Does the -i option to mv have no effect even when you're typing it to the shell directly (not using find)? More on unix.stackexchange.com
🌐 unix.stackexchange.com
November 26, 2013
🌐
Reddit
reddit.com › r/bash › copy and rename file from shell script
r/bash on Reddit: Copy and rename file from shell script
October 26, 2023 -

This is a pretty basic question but I’ve been struggling getting this working for some reason. I am trying to copy a file from one directory to another and renaming it along with the copy. This is being done inside of a shell script, and I have a variable called $filename that stores the NEW file name. Here is the code snippet:

filename="IRcam_fpga_cksm_${checksum}_ver_${version}.pdb"
#filename="This_is_a_file.txt"
echo "filename: ${filename}"
cp ./par/ircam_fpga/designer/impl1/*.pdb output/pl/$filename

The output of the echo command on the console is:

.pdbname: IRcam_fpga_cksm_A415_ver_0x0081

  But the file that gets copied to the new directory does not have the correct name. When I use the version of $filename that is commented out, it works perfectly fine.

Top answer
1 of 5
3
It's hard to tell because the formatting is real messed up You can rename with just: cp /path/to/source/file /path/to/destination/newname
2 of 5
2
The issue you're encountering is because you're overwriting the filename variable after you first set it. When you assign a new value to the filename variable, you essentially lose the previous value, which is why the file is copied with the default This_is_a_file.txt name instead of the intended IRcamfpga_cksm${checksum}ver${version}.pdb. To fix this, make sure that you're not overwriting the filename variable in the script. Here's an updated version of your code: bash filename="IRcamfpga_cksm${checksum}ver${version}.pdb" # Uncomment and use the correct $filename variable without overwriting it echo "filename: ${filename}" # Copy the file and rename it cp ./par/ircam_fpga/designer/impl1/*.pdb output/pl/"${filename}" Explanation: Define the filename correctly: Ensure that the variable filename has the correct value before it's used. Avoid overwriting filename: The second assignment (filename="This_is_a_file.txt") overwrites the first one, which is incorrect. You should either remove or not assign it again. Ensure proper file path: Use "${filename}" to reference the variable safely in the cp command. If checksum and version are being dynamically generated, ensure those variables are correctly populated before being used to build the filename. Here's an example where checksum and version are assumed to be variables with values: bash checksum="A415" version="0x0081" filename="IRcamfpga_cksm${checksum}ver${version}.pdb" echo "filename: ${filename}" # Now copy the file with the correct name cp ./par/ircam_fpga/designer/impl1/*.pdb output/pl/"${filename}" You can try renamer. ai to get easy file renaming solution.
🌐
nixCraft
cyberciti.biz › nixcraft › howto › bash shell › how to rename a file in bash
How To Rename A File In Bash - nixCraft
March 15, 2024 - We need to give SOURCE file to DESTINATION file using the following mv command syntax: $ mv oldname newname $ mv SOURCE DEST $ mv olddir newdir $ mv old-file new-file In short, the mv will rename SOURCE to DEST, or move SOURCE(s) (multiple files) ...
🌐
freeCodeCamp
freecodecamp.org › news › rename-file-linux-bash-command
Rename a File in Linux – Bash Terminal Command
September 30, 2022 - You can use the command below to rename all the files in the folder: for f in *.js; do mv -- "$f" "${f%.js}.html"; done · Let's break down this long string to see what's happening under the hood: The first part [for f in *.js] tells the for loop to process each “.js” file in the directory.
🌐
Linux Hint
linuxhint.com › rename_file_bash
How to Rename a File in Bash – Linux Hint
#!/bin/bash # Take the original filename read -p "Enter the original filename to rename:" original # Take the renamed filename read -p "Enter the renamed filename to rename:" rename # Check the original file exists or not if [ -f $original ]; then # Rename the file $(mv $original $rename) echo ...
Find elsewhere
Top answer
1 of 2
2

If you want to process files only in the top level of the directories (ie: one level deep), then you don't need recursion.

Both of these examples take a list of directories as arguments and rename only the files in those directories which match the more exclusive pattern: *-*.png (to avoid possible failures of the mv command).

A script that does NOT change directory:

In this first script, inside the for loop, the variable name contains the directory path to the file in addition to the base filename.

#!/bin/sh
for dir in "$@"
do
    for name in "name" "${name%-*}.png"
    done
done

A script that DOES change directory:

In this second script, inside the for loop, the name variable contains only the filename, because the current directory has been temporarily changed to the script argument.

The code between the parenthesis ( and ), is executed in a subshell environment which means that changing the current directory, as well as variables set, will not be visible to the outer shell script, eliminating the need to change "back" to the original directory.

#!/bin/sh
for dir in "dir"
        then
            for name in ./*-*.png
            do
                mv "$name" "${name%-*}.png"
            done
        fi
    )
done

Notes About These Two Scripts:

The "$@" expands to the script's command line arguments. The script will silently do nothing with no arguments.

The directory-name arguments can be any absolute path (/path/to/dirx) or relative path (dirx, path/to/diry, ., .., ../x/d1, etc).

Messages will be printed on the standard error stream (stderr) by either mv or cd if a given directory does not exist, or if there are no *-*.png files in a directory. The script will continue processing subsequent directories.

The first line of these scripts can be #!/bin/sh instead of bash because this script uses none of the bash features, thus the more portable, posix compliant, and probably faster, sh can be used. Few scripts require the extra features of the bash shell. For these and other reasons #!/bin/bash is not generally recommended for scripting.

2 of 2
0

This worked for me

 for dir in *; do if cd $dir; then  for filename in *; do mv $filename "$filename.pdf"; done; cd ..; fi; done
🌐
PhoenixNAP
phoenixnap.com › home › kb › sysadmin › how to rename files in linux
How to Rename Files in Linux (Multiple Options and Examples)
December 9, 2025 - The first line is the shebang, indicating a Bash script. The second line begins a for loop to iterate through files in the current directory ending with .txt. The third line uses the mv command on each file found to replace the .txt extension with .pdf.
Top answer
1 of 3
4

Temporary note: there is something wrong - the rename pattern does not handle filenames with path; I'm working on a fix

What is wrong in your command is two things:

find /tmp/dir -name "* *" -type f | rename 's/*/fixed_/g'

  • The -name "* *" matches only file names with a space in it - that's not what you want, right?

    • the solution is to just leave it out; We do not want to exclude files matching some name - we want all.
  • The rename pattern is wrong in two ways

    • you used a shell glob pattern, but it needs to be a regular expression, in short a regex (It can be some general perl expression - let's ignore it and use only s///g)
    • the fixed pattern would match the complete name, and replace it with fixed_. You want to "replace" the "first 0 characters" with fixed_, technically. That's the start of the line, matched with ^. We can leave out the g because there is only one replacement needed per line.

Putting it together, it looks like this:

find /tmp/dir -type f | rename 's/^/fixed_/'

2 of 3
1

It seems your system features the older version of rename that doesn't use regular expressions. You can rename your files with

cd /tmp/dir/
for f in *\ * ; do
    [[ -f $f ]] && mv "$f" fixed_"$f"
done

(untested)

For the rename command with regex support, you have to change the regular expression: * needs something to operate on, it means "repeat the previous thing zero or more times". You don't want to replace anything, you want to prepend, so use ^ which stands for the beginning of the string:

rename 's/^/fixed_/'
🌐
Stack Exchange
unix.stackexchange.com › questions › 671761 › rename-2-files-using-shell-script
Rename 2 files using shell script - Unix & Linux Stack Exchange
I had many syntax errors in my script, but i am used https://www.shellcheck.net/ to correct them. ... #!/bin/sh #_start while getopts o: flag do case "${flag}" in o) OPTION=${OPTARG};; *) esac done # declare variable RENAME="rename" DEFAULT="default" # show all ExportP* files ls '/home/dev/Documents/Work/info/Target_script/first'* # rename file if [ "$OPTION" = "$RENAME" ]; then mv '/home/dev/Documents/Work/info/Target_script/first1.txt' '/home/dev/Documents/Work/info/Target_script/first1_ori.txt' mv '/home/dev/Documents/Work/info/Target_script/first2_SL.txt' '/home/dev/Documents/Work/info/Tar
🌐
nixCraft
cyberciti.biz › nixcraft › tutorials › linux › linux rename multiple files at a shell prompt
Linux Rename Multiple Files At a Shell Prompt - nixCraft
February 26, 2025 - WARNING: This is a demo script and it is not very safe to use. I suggest either use rename/zmv or POSIX shell method. #!/bin/bash # To remove blank space if [ $# -eq 0 ]; then echo "Syntax: $(basename $0) file-name [command]" exit 1 fi FILES=$1 CMD=$2 for i in $FILES do # remove all blanks and store them OUT OUT=$(echo $i | sed 's/ *//g') if [ "$CMD" == "" ]; then #just show file echo $OUT else #else execute command such as mv or cp or rm [ "$i" != "$OUT" ] && $($CMD "$i" "$OUT") fi done
🌐
Hostinger
hostinger.com › home › tutorials › how to rename files in linux using the mv and rename commands
How to Rename Files In Linux Using the Command Line
April 28, 2025 - To run the bash script, enter the command below. Replace the file name and directory path according to your own: ... If you encounter an error, ensure your current user account has the execute permission over the file. Otherwise, enter the chmod command to change the privilege: ... The rename command gives you more flexibility in modifying the files.
🌐
Baeldung
baeldung.com › home › files › how to rename multiple files in linux by removing the extension
How to Rename Multiple Files in Linux by Removing the Extension | Baeldung on Linux
March 18, 2024 - Then, let’s add these lines of code in the script file: #!/bin/bash for f in *.txt; do mv -- "$f" "${f%.txt}.pdf" done · We then press Ctrl + S and Ctrl + X to save and exit editor. ... In the Bash script, we can also use mv in combination with cut to achieve the same result. For this, we’ll add the following code in the Bash script:
🌐
LinuxConfig
linuxconfig.org › home › how to rename multiple files on linux
Rename Multiple Files on Linux with mv, rename, mmv
September 22, 2025 - We can also change the file extension of every file. The following command will change all files with the .log extension to .txt. $ for i in *.log; do mv -- "$i" "${i%.log}.txt"; done · You can also use the find command, along with -exec option or xargs command to rename multiple files at once.
Top answer
1 of 1
1

If we can assume that your file names do not contain ; (this is a huge assumption, ; is perfectly valid in file names, so you need to be sure about this), then you can just read your input text file, split on ; and save the result in two variables, allowing you to rename:

while IFS=';' read old new ; do mv "$old" "$new" ; done < filenames.csv

Here, we set the input field separator (IFS) to a ;, then read the input file, split on ; and assign the old and new filenames to their respective variables.

Now, your input example also has spaces around the ;. This means that the file name isn't "this_is_a_file.ext" but "this_is_a_file.ext " with an extra space, and that file won't exist. So before running the command above, you need to remove those extra spaces. You can do this with sed, telling it to replace all cases of two or more spaces ( *, that is one space, then another space and a *) around a ; with just the ;:

$ sed 's/  *;  */;/g' filenames.csv 
this_is_a_file.ext;new_filename_1.ext
this_is_another_file.ext;new_filename_2.ext
this is a filename with spaces.ext;new_filename_3.ext

Combining the two commands gives the one you really want to run:

$ sed 's/  *;  */;/g' filenames.csv |  
   while IFS=';' read old new ; do 
     echo "mv \"$old\" \"$new\"" ; 
done 
mv "this_is_a_file.ext" "new_filename_1.ext"
mv "this_is_another_file.ext" "new_filename_2.ext"
mv "this is a filename with spaces.ext" "new_filename_3.ext"

Once you are sure that is the right output, remove the echo and run again to actually rename the files:

sed 's/  *;  */;/g' filenames.csv |  
   while IFS=';' read old new ; do 
     mv -- "$old" "$new" ; 
done 

The -- is there to protect against file names starting with -. See What does "--" mean in terminal commands?.