LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   Mass file renaming (https://www.linuxquestions.org/questions/linux-newbie-8/mass-file-renaming-4175453776/)

Madhu Desai 03-12-2013 09:13 AM

Mass file renaming
 
i'm looking for how to rename files in mass quantity. basically i am completely moving from windows (ntfs) to CentOs (ext4). in windows i used to give spaces in between file names, now i want to replace spaces with "-" or "_", so that i get the full file name when i hit tab in terminal.

i've searched google and also looked into "similar threads" of LQ, but could not find answer for my specific requirement. either they are for particular directory or have a pattern/incremental in nature, for example renaming *.jpeg files, file1*.jpg file123.jpg etc.

i'm looking for solutions based on "find" command.

for example:

Code:

# find /dc/cbt/ -type f -iname "*bind*"

/dc/cbt/Books/DNS Bind Configuration in RHEL 6.pdf
/dc/cbt/Linux/Install & Configure BIND DNS Server in CentOS.mp4
/dc/cbt/Linux/YouTube/rhel 6 bind primary dns server in redhat linux.flv

i know how to display modified files, but don't know how to write them permanent. that's the problem :doh:

Code:

# find /dc/cbt/ -type f -iname "*bind*" | sed "s/ /_/ig" | tr "[:upper:]" "[:lower:]"

/dc/cbt/books/dns_bind_configuration_in_rhel_6.pdf
/dc/cbt/linux/install_&_configure_bind_dns_server_in_centos.mp4
/dc/cbt/linux/youtube/rhel_6_bind_primary_dns_server_in_redhat_linux.flv

thanks...

millgates 03-12-2013 10:12 AM

How about something like this?

Code:

while read -r name; do
    lower="${name,,}"
    newname="${lower// /_}"
    echo "$name --> $newname"
    # mv "$name" "$newname"
done < <(find /dc/cbt/ -type f -iname "*bind*")

Be very careful with this. Backup your data.
You may also look at the manpage of rename command, which is quite a useful tool for mass renaming

suicidaleggroll 03-12-2013 10:21 AM

Code:

#!/bin/bash

find /dc/cbt/ -type f -iname "*bind*" | while read line; do
  oldfile=$line
  newfile=${oldfile// /_}
  newfile=${newfile,,}
  echo mv "$oldfile" "$newfile"
done

Once you're sure it's working correctly, remove the "echo" to actually rename the files.


edit: too slow

Madhu Desai 03-12-2013 01:16 PM

Finally...
 
Thanks millgates & suicidaleggroll. I tried both, and both works great!!! :hattip:

while trying, i realised that certain files have multiple spaces. so i changed a little. i think when both scripts are translated to machine language, they will be same.

Code:

#!/bin/bash
while read -r name; do
    lower="${name,,}"
    newname=`echo "$lower" | sed 's/  */_/g'`
    echo "$name --> $newname"
    mv "$name" "$newname"
done < <(find /dc/cbt/ -type f -iname "*bind*")

Code:

#!/bin/bash
find /dc/cbt/ -type f -iname "*bind*" | while read line; do
  oldfile=$line
  newfile=`echo "$oldfile" | sed 's/  */_/g'`
  newfile=${newfile,,}
  mv "$oldfile" "$newfile"
done


millgates 03-12-2013 02:20 PM

As an alternative to sed you could use bash extglob:

Code:

shopt -s extglob
foo="a  b  c"

# replace spaces with underscores
echo "${foo//+( )/_}"

also, I would recommend to use the $( command ) syntax for command substitution. It handles nesting and double quotes nicely, unlike the backticks.

Madhu Desai 03-12-2013 03:54 PM

Quote:

shopt -s extglob
??? :scratch:

chrism01 03-12-2013 08:11 PM

Re shopt = shell options ie amend the way the shell works.
See http://linux.die.net/man/1/bash and search for shell builtin commands, then shopt, then extglob within that.
Its about 80% of the way down that page or google for examples etc.

Madhu Desai 03-13-2013 03:21 AM

Thanks.


All times are GMT -5. The time now is 04:12 AM.