3

I want to rename the files in a directory to sequential numbers, based on this rule :
filename-[some date] => filename-[previous day's date]

For example, file20170329 file20170328 and file20170327 are to be renamed to file20170328 file20170327 and file20170326.

I have like 100 file, so I need a better trick than renaming each file individually.

  • should it support only today's date => yesterday date or any-date to one day before? should it support e.g. 20170301 -> 20170228? – Yaron Mar 29 '17 at 10:57
  • Yesterday date is a single "number" (20170329), how would you rename to yesterday two files? What is your actual goal? – EnzoR Mar 29 '17 at 11:04
  • Three questions: 1. while renaming, possible temporary dupes will occur, is that correct? 2. Do the files have extension? If so, always the same? 3. is "file" just an example, and is the date always on the same position in the name, and in the same format? – Jacob Vlijm Mar 29 '17 at 12:16
  • @Yaron: fortunately file dates are actually between 20170321 and 20170330. Uqbar : I want to rename all the files to yesterday, so at the end there will be only one file per day. – storm Mar 29 '17 at 12:40
  • @JacobVlijm: 1- yes 2- all of them are .gz files 3- yes file is just an example , neither position nor format are the same – storm Mar 29 '17 at 12:43
4

The following script:

  • for each file
  • If filename is greater than 8 (i.e. is able to hold a date)
  • basefilename hold the filename without the last 8 chars
  • TODAY - holds the last 8 chars (the date)
  • YESTERDAY - holds one day before $TODAY as 8 chars
  • Instead of using mv I created a /tmp/storage folder, and the script will copy the files to that location. This way, renaming one file won't corrupt another file if by any chance the basefilename for both files is the same, but the date is differ in one day

Note: In order to allow the script to execute the cp one should remove the echo from the echo cp ... line

mkdir -p /tmp/storage
for f in *
do
  if [ "${#f}" -gt 8 ]; then
    filebasename=${f::-8}
    TODAY=${f: -8}
    YESTERDAY=`date '+%C%y%m%d' -d "$TODAY-1 days"`
    echo cp $f /tmp/storage/${f//$TODAY}$YESTERDAY; 
  fi
done

example:

$ ls *20*
aaa2hhh20170329  aaahhh20170329  xajds20170222  xajsxs20170224

script result:

cp aaa2hhh20170329 /tmp/storage/aaa2hhh20170328
cp aaahhh20170329 /tmp/storage/aaahhh20170328
cp xajds20170222 /tmp/storage/xajds20170221
cp xajsxs20170224 /tmp/storage/xajsxs20170223
  • I think you can just use a shell glob, for f in *, instead of running ls. Bash sorts the filenames given by glob anyway. – ilkkachu Mar 29 '17 at 11:47
  • @Zanna - can you please double check? for each file, the original date is taken and is replaced with the previous day – Yaron Mar 29 '17 at 14:11
  • It's working with some adjustments , thanks :) – storm Mar 29 '17 at 14:15
  • @storm - great, I've made a few adjustments myself a few seconds ago (using cp to /tmp/storage instead of mv) – Yaron Mar 29 '17 at 14:18
  • 1
    Maybe I was testing an earlier version. Can't check now but looks like it should work and OP says it does, so +1! – Zanna Mar 29 '17 at 14:20
4

If you have 100 files (and have access to perl rename, generally the case in Ubuntu) you could use:

for n in {100..1}; do rename -n "s/$(date --date="$n days ago" +"%Y%m%d")/$(date --date="$(($n+1)) days ago" +"%Y%m%d")/" *; done

Now, when you use -n for testing, it complains like this:

rename(file20170217, file20170216)
file20170218 not renamed: file20170217 already exists
file20170219 not renamed: file20170218 already exists

But when you run it without -n the file no longer exists, so the renaming is successful:

for n in {100..1}; do rename "s/$(date --date="$n days ago" +"%Y%m%d")/$(date --date="$(($n+1)) days ago" +"%Y%m%d")/" *; done

If you have more than 100 files, you need to increase the range to {150..1} or whatever.

This is very slow. It will take maybe 2 minutes or more to rename 100 files. But it works.

0

or if you prefer GUI approach, give krename a try, it has a lot of modules and you can write custom scripts in it, "date system function", "date time plugin" could work for youKrename GUI for plugins

http://www.krename.net/home/

sudo apt-get install krename

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.