-3
I have files like below in a directory in unix:
2007 CSE Classes.csv
2007 EEE Classes.csv
2007 ECE Classes.csv
2008 CSE Classes.csv
.
.
.
2018 ECE Classes.csv

Need to rename those like below:

2007 CSE Classes_20190129.csv
2007 EEE Classes_20190129.csv
2007 ECE Classes_20190129.csv
2008 CSE Classes_20190129.csv
.
.
.
2018 ECE Classes_20190129.csv

There are spaces in the file names as well.

The date added will change based on the day the script is run.

BPQ
  • 55
  • 1
  • 7

2 Answers2

1

you can simply do it with this I believe,

for i in `find /path/to/yourFiles/directory -name "*.csv"` ; do mv $i ${i}_$(date +"%m-%d-%y").csv ; done
Anıl Aşık
  • 360
  • 1
  • 15
  • What's that `find` good for? Why `+"%m-%d-%y"`? That's not at all what the question asked. Also unclear why you would want to invoke `date` so many times instead of just once. And it will break badly because of the spaces in the file names (2x). That's at least five mistakes in one line, which is, maybe, a bit suboptimal. – Andrey Tyukin Jan 31 '19 at 09:25
0

First, you need to get a list of the files. You can use globbing for that, like *Classes.csv.

Then, you need to loop over this list. If you start out like this, it should print out all of the files:

for file in *Classes.csv; do
    printf %s\\n "$file"
done

If that looks right, you now need to know the filename you want to rename to. Here I will use the % operator in a parameter expansion to clip the .csv off the end. This is documented in man bash and the POSIX shell specifications as removing the smallest matching suffix from the string.

for file in *Classes.csv; do
    file_noext=${file%.csv}
    printf '%s -> %s\n' "$file" "$file_noext"
done

That's halfway there, now we need to add the date and re-add the .csv suffix. The date is similar to %F format (2019-01-29) but contains no hyphens. I would recommend using the %F format instead if you are free to choose, as it is more obvious to the casual observer that it is a date. For your format, you will need %Y%m%d (see man 1 date). I use the $(...) command substitution syntax here to capture the output of the date command.

today=$(date +%Y%m%d)
for file in *Classes.csv; do
    file_noext=${file%.csv}
    printf '%s -> %s\n' "$file" "${file_noext}_${today}.csv"
done

If all the output looks correct, you will want to make the final change and use mv instead of just printing the filenames:

today=$(date +%Y%m%d)
for file in *Classes.csv; do
    file_noext=${file%.csv}
    mv -- "$file" "${file_noext}_${today}.csv"
done

And that should be all that's necessary.

Your question explicitly asked for a for loop, but normally I would just use the util-linux rename utility:

rename 'Classes' "Classes_$(date +%Y%m%d)" ./*Classes.csv

Note that this one-liner will not work on Ubuntu Linux as they provide an incompatible rename utility. (On such systems you will need to invoke it as rename.ul)

Score_Under
  • 1,189
  • 10
  • 20