8

How can i rename all the files in a specific directory where the files contains blanks spaces and special characters ($ and @) in their names?

I tried the rename command as follows to replace all the spaces and special characters with a _:

$ ls -lrt
total 464
-rwxr-xr-x. 1 pmautoamtion pmautoamtion 471106 Jul 17 13:14 Bharti Blocked TRX Report Morning$AP@20150716.csv


$ rename -n 's/ |\$|@/_/g' *
$ ls -lrt
total 464
-rwxr-xr-x. 1 pmautoamtion pmautoamtion 471106 Jul 17 13:14 Bharti Blocked TRX Report Morning$AP@20150716.csv
$

The command works but won't make any changes in the file names and won't return any error as well. How can in fix this and are there other ways as well?

8

The -n flag is for

--no-act

No Action: show what files would have been renamed.

So it's normal if you don't have any changes.

Regarding your command, it's working for me:

$ touch "a @ test"
$ ls
a @ test
$ rename -n 's/ |\$|@/_/g' *
a @ test renamed as a___test

Maybe depending on your shell, you have to escape the |

$ rename -n 's/ \|\$\|@/_/g' *

Or you can use the […] notation to group characters:

$ rename -n 's/[ @\$]/_/g' *
  • I tried all the three without -n option and still it won't change the name of the file. I doesn't give any error for any of the 3 types mentioned above. Maybe the rename command doesn't work for some reason. Is there any other way to change all the files in a directory with spaces or $ or @ in their names? – Ankit Vashistha Jul 17 '15 at 8:12
  • @AnkitVashistha does rename -n 's/./_/g' * outputs something? – fredtantini Jul 17 '15 at 8:22
  • It doesn't give anything, no output, no error. It just lands on next command line. – Ankit Vashistha Jul 24 '15 at 9:59
3

You could try like this:

for file in ./*Block*                                       
do echo mv "$file" "${file//[ ()@$]/_}"
done

If you're happy with the result, remove the echo before mv to actually rename the files.

  • One of the best solution i have gone through, I was trying for this for so long – Sushin Pv Jan 11 at 14:34
1

This one just strip the special characters from filenames

for file in *; do mv "$file" `echo $file | tr -cd '.A-Za-z0-9_-'` ; done
ॐNámásté Egész-ség.mkv --> NmstEgsz-sg.mkv

put echo after ; do to test before, like:

for file in *; do echo mv "$file" `echo $file | tr -cd '.A-Za-z0-9_-'` ; done

Another solution:

rename -v 's/[^a-zA-Z0-9\.\s_-]//g' *.* && rename -v 's/[\s]/_/g' *.*
ॐNámásté Egész-ség.mkv --> Nmst_Egsz-sg.mkv

-n option to test before.

0

Since the rename command didn't work for me for unknown reasons and i do not get any other answers for my question, i myself tried to make an effort to make the rename possible. This might not be the best approach to rename the files but it worked for me and this is why i would like to post it as an answer so that if anyone else reads this might get some help to change the file names the way i did.

Now for me, i know that all the files will have a specific text in their names which is the word "Block". Following are the file names before their renaming was done:

anks@anks:~/anks$ ls -lrt
total 4
-rw-r--r-- 1 anks anks   0 Jul 25 14:47 Bharti TRX Block Report$AP@12Jul15.csv
-rw-r--r-- 1 anks anks   0 Jul 25 14:47 Bharti TRX Block Report$HP@12Jul15.csv
-rw-r--r-- 1 anks anks   0 Jul 25 14:47 Bharti TRX Block Report$CH@12Jul15.csv
-rw-r--r-- 1 anks anks   0 Jul 25 14:47 Bharti TRX Block Report$KK@12Jul15.csv
-rw-r--r-- 1 anks anks   0 Jul 25 14:48 Bharti TRX Block Report$UW@12Jul15.csv

Now i have written a small shell script to make this possible. Following is the code:

#!/bin/bash

PATH="/home/ebfijjk/anks"

# Put the old filenames in a file.
ls $PATH | grep Block >> oldValues

# Put the new names without " " or "@" or "$" in another file
cat oldValues | sed 's/\$/_/g' | sed 's/\@/_/g' | sed 's/ /_/g' >> newValues

# Create a new file with Old names and New names seperated by a #.
paste -d'#' oldValues newValues >> oldAndNew

# Read the file with both old and new names and rename them with the new names.
while IFS='#'; read oldValue newValue
do
    mv "$oldValue" "$newValue"

done < oldAndNew

rm oldValues newValues oldandNew

And that's it, when i run the script, it renames all the file names having blank spaces () or $ or @ with _ instead of these characters.

  • you can replace cat foo | sed S1 | sed S2 | sed S3 >> bar by sed -e S1 -e S2 -e S3 foo >> bar – Archemar Jul 25 '15 at 15:17
  • 2
    @Archemar - or simply sed 's/[ ()@$]/_/g' or sed 'y/ ()@$/_____/' – don_crissti Jul 25 '15 at 16:17
  • Thank you don_crissti and Archemar for your comments and suggestions. – Ankit Vashistha Sep 13 '16 at 7:47
0

I have been looking for a solution to this problem for a while now. I work on old closed systems that can't have new packages installed. I don't have the rename command. Finally I wrote a script that appears to work with all keyboard entered special characters. ~@#$%^&*()-_=+[]{}\|;:",<.>?' The script will rename every file and directory in the current directory. It will replace all special characters,except -_. with the _ character. The outfile= line can be modified to use a different character for replacement if desired. Replace |_| with |.| to use the . character for example.

#!/bin/bash

for file in ./*
do
  infile=`echo "${file:2}"|sed  \
         -e 's|"\"|"\\"|g' \
         -e 's| |\ |g' -e 's|!|\!|g' \
         -e 's|@|\@|g' -e 's|*|\*|g' \
         -e 's|&|\&|g' -e 's|]|\]|g' \
         -e 's|}|\}|g' -e 's|"|\"|g' \
         -e 's|,|\,|g' -e 's|?|\?|g' \
         -e 's|=|\=|g'  `
  outfile=`echo "${file:2}"|sed -e 's|[^A-Za-z0-9._-]|_|g'`
  mv "$infile" ${outfile} &
done

exit
0

looking for a handsome script to remove special characters as well as german special characters, replacing them with universal ones to not remove useful information I've updated the last version of the script which had some minor issues resulting in:

#!/bin/bash

for file in ./*
do
  infile=`echo "${file:2}"|sed  \
         -e 's|"\"|"\\"|g' \
         -e 's| |\ |g' -e 's|!|\!|g' \
         -e 's|@|\@|g' -e 's|*|\*|g' \
         -e 's|&|\&|g' -e 's|]|\]|g' \
         -e 's|}|\}|g' -e 's|"|\"|g' \
         -e 's|,|\,|g' -e 's|?|\?|g' \
         -e 's|=|\=|g'  `
  outfileNOSPECIALS=`echo "${file:2}"|sed -e 's|[^A-Za-z0-9._-]|_|g'`
  outfileNOoe=`echo $outfileNOSPECIALS| sed -e 's|ö|oe|g'`
  outfileNOae=`echo $outfileNOoe| sed -e 's|ä|ae|g'`
  outfileNOue=`echo $outfileNOae| sed -e 's|ü|ue|g'`
  outfileNOOE=`echo $outfileNOue| sed -e 's|Ö|OE|g'`
  outfileNOAE=`echo $outfileNOOE| sed -e 's|Ä|AE|g'`
  outfileNOUE=`echo $outfileNOAE| sed -e 's|Ü|UE|g'`
  outfileNOss=`echo $outfileNOUE| sed -e 's|ß|ss|g'`
  outfile=${outfileNOss}
  if [ "$infile" != "${outfile}" ]
  then
        echo "filename changed for " $infile " in " $outfile
        mv "$infile" ${outfile}
  fi
done

exit

resulting in:

enter image description here

@don_crissti: He's doing the hokus-pokus with the infile since linux would have it's own issues with handling special characters when moving the filename.

  • 1
    special characters ? which ones ? – don_crissti Feb 22 '17 at 0:00
  • Space, At symbol, Ampersand .... – Matthias R. Wiora Feb 22 '17 at 7:38
  • There is no problem moving a file with a name which contains special characters (including a newline)... You're probably not familiar with the shells (and btw, this has nothing to do with linux, it's a shell feature...) – don_crissti Feb 22 '17 at 17:42
  • mh okay - you're maybe right – Matthias R. Wiora Feb 23 '17 at 12:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.