I have to convert multiple video files in a folder. I have to rename each one of them but I need the script to prompt me to write a custom name for each filename. Here is what I've got so far:

  1. First I need to remove the filename spaces which my script does with that command:

    for f in *' '*; do mv "$f" "`echo $f | sed -e 's/ /_/g'`"; done
  2. I remove the extension of the files because I don't need it for the conversion. I use this command:

    for x in *; do mv $x $(echo ${x%*.*}); done

After that I need a for loop to rename each file in the pattern:

for i in * ; do mv $i $customname; done

The problem is that I need in that phase the script to prompt me what name to add in the variable $customname for each file. Something like this:

Rename file1 to:

Rename file2 to:
  • 2
    The echo command in $(echo ${x%*.*}) is completely superfluous. – And if you're just looking to remove the file extension you should not be using *.* (which is only incidentally working because the first asterisk is matching zero characters every time), instead use .*. I.e. $(echo ${x%*.*}) should be ${x%.*}.
    – zrajm
    Commented Sep 6, 2013 at 8:40
  • 2
    And if you're using bash (or zsh for that matter) then the sed invocation is not necessary either. Use ${f// /_} to replace all occurances of space with underscore in $f.
    – zrajm
    Commented Sep 6, 2013 at 8:43
  • 2
    If you quoted properly everywhere, you wouldn't have to remove spaces in the first place. Commented Sep 6, 2013 at 9:57

2 Answers 2


Just use read to read one line from STDIN, like this.

for FILE in *; do
    echo "Rename '$FILE' to:"
    read NAME
    mv "$FILE" "$NAME"

This example would require you to press Ctrl-C to abort when you're done, but you could add an extra if case to abort e.g. if no name was entered.

EDIT: If you want all your destination files to have the same file extension as the original file (e.g. if the a file was called pogo.jpg you'd want the renamed file to keep its .jpg ending, and not have to type that manually) you can change the mv command in the above loop to:

mv "$FILE" "$NAME.${FILE##*.}"

The ${FILE##*.} stuff in the string above means:

  • ${FILE...} display the variable $FILE, but…
  • ## remove longest matching string from the beginning (just one # matches shortest)
  • * match zero or more of any character
  • . match a literal period

Only if the entire expression (*.) matches will it be removed, thus if there is no period in the original file name, you'll get a weird result, and the new filename will be NEWNAME.OLDNAME.


Here's what I used for my USB-PVR before I wrote a script that gets the names from the TV programme...


for f in "$@"
    echo Playing "$f"...
    mplayer "$f"
    echo That was "$f".
    read -p "New name? " newname

    if [ "$newname" != "" ]
        mv -v -i "$f" PVR-"$newname".mkv

    sleep 1

Really tedious way to rename files if I may say so ...

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .