-1

I've got a small problem with my bash script. I try to change file name in current directory for whole files with txt extension to text extension. For exampel 1.txt to 1.text

My script looks like this now:

#!/bin/bash
FILES=`ls /home/name/*.txt`
NAME=*.txt
RENAME=*.text

for file in FILES
do 
mv $NAME $RENAME
done

i try whole combination with single, double quotes and backticks and I receive errors all the time.

Do you have some ideas how to receive wildcards "*" in bash?

Thanks.

Mostafa Hussein
  • 11,063
  • 3
  • 36
  • 61

3 Answers3

0

That's not at all how you do that.

#!/bin/bash
shopt -s nullglob

OLD=.txt
NEW=.text
FILES=(/home/name/*"$OLD")    

for file in "${FILES[@]}"
do
  mv "$file" "${file%$OLD}$NEW}"
done
Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
0

There are a number of issues with your script. Firstly, you shouldn't run ls and attempt to store its output like that. If you want to iterate through those file, just do it in the loop:

for file in /home/name/*.txt

Now the shell is doing all the work for you, and as a bonus handling any kind of weird filenames that you might have.

In your example you were looping over the literal string "FILES", not the variable, but I guess that was just a typo.

The built-in way to change the filename is to use a parameter expansion to remove the old one, then concatenate with the new one:

old=txt
new=text

for file in /home/name/*"$old"
do
    mv "$file" "${file%$old}$new"
done

If it is possible that there are no files matching the glob, then by default, the /home/name/*.txt will not be expanded and your loop will just run once. then you have a couple of options:

  • use shopt -s nullglob so that /home/name/*.txt expands to null, and the loop is skipped
  • add an explicit check inside the loop to ensure that $file exists before trying to mv:

    for file in /home/name/*"$old"
    do
        [ -e "$file" ] || continue
        mv "$file" "${file%$old}$new"
    done
    
Tom Fenech
  • 72,334
  • 12
  • 107
  • 141
-1
  1. You can use rename to rename filenames.

    rename .txt .text /home/name/*.txt
    
  2. And if you want to do this by looping, you can

    for FILE in /data/tmp/*.txt; do
        mv  "${FILE}" "${FILE/.txt/.text}"
    done
    
Toby Speight
  • 27,591
  • 48
  • 66
  • 103
Bjjam
  • 71
  • 6
  • I've added the important quoting you omitted. You still have the issue that the parameter substitution will replace the *first* `.txt` in the name, rather than the last. – Toby Speight May 22 '18 at 13:36