2

I have script below saved in MYFILES dir to create x number of files & their timestamps was randomly run with multiple years & months.

for i in {1938..2037}; do   
    ## create a file with a random month
    touch -d "${i}-$((RANDOM % 12 + 1))-01" file_$((i-1937))
    done  
output:
-rw-r--r-- Users   0 Jul  1  1938 file_1
-rw-r--r-- Users   0 Jun  1  1947 file_10
-rw-r--r-- Users   0 Oct  1  2037 file_100 

Kindly help on how to create script that would analyze the contents of MYFILES dir and sort the files in subdir FILES2, then rename files according to their timestamps.

Sample output should be:

rw-r--r-- Users   0 Jul  1  1938 file_JUL1938
rw-r--r-- Users   0 Jun  1  1947 file_JUN1947
rw-r--r-- Users   0 Oct  1  2037 file_OCT2037
0
ls -l file_* |
awk '{system("echo mv -v -- " $9 " file_" toupper($6) $8);}'

For real file renaming, the echo word should be removed.

Explanation

  1. ls -l file_* | awk - list all files and send them to the awk.
  2. system() - execute the shell command.
  3. mv -v -- " $9 " file_" toupper($6) $8 -
    • mv - the usual mv command executed in the shell.
    • toupper(str) - return a copy of the string str, with all the lowercase characters in str translated to their corresponding uppercase counterparts.
    • $6 - month: Aug, Jul, Feb.
    • $8 - year: 1938, 1947, 2037.
    • $9 - filename: file_1, file_10, file_100.

Files

$ ls -l file_*
-rw-rw-r-- 1 user user 0 Aug  1  1938 file_1
-rw-rw-r-- 1 user user 0 Jul  1  1947 file_10
-rw-rw-r-- 1 user user 0 Feb  1  2037 file_100

Output

mv -v -- file_1 file_AUG1938
mv -v -- file_10 file_JUL1947
mv -v -- file_100 file_FEB2037
3

Use GNU date and stat to gather and reverse the information:

for f in *
do
  ref=$(stat -c %y "$f" | awk '{print $1}')
  mon=$(date -d "$ref" +%b)
  year=$(date -d "$ref" +%Y)
  echo mv -- "$f" "file_${mon^^}${year}"
done

This uses a bashism to upper-case the month; if that's not available, use echo "$mon" | tr '[:lower:]' '[:upper:]'. Another alternative, thanks to steeldriver, is to use recent date functionality to return the upper-case version of the month natively: date +%^b.

To create the sample files:

touch -d 1938-07-01 file_1
touch -d 1947-06-01 file_10
touch -d 2037-10-01 file_100

Ouput of the script on the sample input:

mv -- file_1 file_JUL1938
mv -- file_10 file_JUN1947
mv -- file_100 file_OCT2037
  • 2
    At least in recent versions of GNU date, you should be able to use ^ as part of the format specifier to get an upper-case month + year directly e.g. date +%^b%Y – steeldriver Sep 22 '17 at 17:04
  • I suppose yet another "shortcut" could be: read year mon <<< $(date -d "$ref" +"%Y %^b") – Jeff Schaller Sep 22 '17 at 17:08

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.