1
votes

I have a buch of logs with names in "filename.logdate month year" (for example, filename.log25 Aug 2015, note there are space between the date/month/year) and I'd like to change them to "filename.logmonthdateyear" (for example filename.logOct052015, with no space). These files are in a bunch of sub folders which makes it more challenging.

Parent Folder --- sub folder1 file1 file2 --- sub folder2 file3 file4 etc.

Can anyone suggest a bash script that can do this? Thank you!

2
Welcome to StackOverflow. Please see stackoverflow.com/help/how-to-ask and stackoverflow.com/help/mcve. We can help with a script you've written. We don't accept coding assignments at StackOverflow. /// You need to write a short script that pulls the date (key off ".log"), splits it into its three parts, and reassembles them in your desired order. I also recommend that you put the year first and perhaps change the month to a number, such as .log2015-10-05, since this lets you easily sort the files into chronological order.Prune

2 Answers

2
votes

find and rename should do the trick

strawman example:

to go from

...
├── foo/
│   ├── file name with spaces
│   └── bar/
│       └── another file with spaces
...

you can use

find foo/ -type f -exec rename 's/ //g' '{}' \;

to get

...
├── foo/
│   ├── filenamewithspaces
│   └── bar/
│       └── anotherfilewithspaces
...

in your case:

in your case, it would be something like

find path/to/files/ -type f -exec rename 's/ //g' '{}' \;

but you can use fancier filters in your find command like

find path/to/files/ -type f -name *.log* -exec rename 's/ //g' '{}' \;

to select only .log files in case there are other file names with spaces you don't want to touch


heads up:

as pointed out in the comments there's the potential to overwrite files if their names only differ by space placement (e.g., a bc.log and ab c.log if carelessly renamed would end up with a single abc.log).

for your case, you have two things on your side:

  1. rename will give you a heads up as long as you're not using it's --force option and will give you a helpful message like ./ab c.log not renamed: ./abc.log already exists
  2. your files are named programatically, and you're stripping the spaces in dates, so, assuming that's all you have in there, you shouldn't have any problems

regardless, it's good to be mindful of this sort of thing

0
votes

This is a way to do it with just Bash (4+) and 'mv':

# Prevent breakages when nothing matches patterns
shopt -s nullglob

# Enable '**' matches (requires Bash 4)
shopt -s globstar

topdir=$PWD
for folder in **/ ; do
    # Work in the directory to avoid problems if its path has spaces
    cd -- "$folder"
    for file in *' '*' '* ; do
        # Use the '-i' option to prevent silent clobbering
        mv -i -- "$file" "${file// /}"
    done
    cd -- "$topdir"
done

If there is just one level of subfolders (as stated in the question), the requirement for Bash 4+ can be dropped: remove the shopts -s globstar, and change the first line of the outer loop to for folder in */ ; do.