0

On Solaris, I've got a script that succesfully do that:

USER,REPORT_NAME,DD:MM:HH24.pdf -> USER,REPORT_NAME,DD_MM_HH24.pdf

The one-liner is this:

for f in *:*; do mv "$f" $(echo "$f" | tr ':' '_'); done

But now, I have to undone it, and also, filter by creation date (reports generated the last 15 days, for example). So, for the reports generated the last 15 days, I have to do this rename:

USER,REPORT_NAME,DD_MM_HH24.pdf -> USER,REPORT_NAME,DD:MM:HH24.pdf

How can I replace only the characters (_) in the DD_MM_HH24 part, and don't touch the REPORT_NAME part in the filename? And filter by modification date the reports?

Posible Solution: I've come up with a non very elegant solution.. Is executing 2 times the command, to replace the last occurrence of "_" each time:

$ echo "ADMIN,IN_CO_GE,17-09-2015,11_17_06.pdf" |  sed 's/\(.*\)_/\1:/'
ADMIN,IN_CO_GE,17-09-2015,11_17:06.pdf
$ echo "ADMIN,IN_CO_GE,17-09-2015,11_17:06.pdf" |  sed 's/\(.*\)_/\1:/'
ADMIN,IN_CO_GE,17-09-2015,11:17:06.pdf

Final solution Thanks to chaos, this is the final solution to my problem:

for f in *; do mv "$f" $(echo "$f" | nawk -F, '{OFS=",";gsub(/_/, ":", $NF)}1'); done
1

You can use awk for that:

for f in *; do
  mv "$f" $(echo "$f" | awk -F, '{OFS=",";gsub(/_/, ":", $NF)}1')
done

This will replace the _ with :, but only in the last field delimited by ,:

  • -F, sets awks delimiter to ,
  • OFS=","; sets the ouput field separator to ,
  • gsub(...) replace all _ with : in the last field $NF
  • The 1 at the end is a true condition, that awk prints the whole line.

Edit: On Solaris, you have to use nawk (which is the only awk on Solaris system that has the gsub() function) instead of the old awk:

for f in *; do
  mv "$f" $(echo "$f" | nawk -F, '{OFS=",";gsub(/_/, ":", $NF)}1')
done

Edit 2: For files whose mtime is newer than 30 days:

for f in *; do
  [ $(stat -c %Y "") -gt $(expr $(date +%s) - 30 \* 86400) ] && \
    mv "$f" $(echo "$f" | nawk -F, '{OFS=",";gsub(/_/, ":", $NF)}1')
done
  • Thanks, chaos.. I've got a problem executing this stament: awk: syntax error near line 1 awk: illegal statement near line 1 awk: syntax error near line 1 awk: bailing out near line 1 mv: Insufficient arguments (1) Usage: mv [-f] [-i] f1 f2 mv [-f] [-i] f1 ... fn d1 mv [-f] [-i] d1 d2 My system is a SunOS 5.10 Generic_147148-26 i86pc i386 i86pc – Aitor Sep 22 '15 at 7:37
  • 1
    @Aitor can you try again? I changed the gsub() part – chaos Sep 22 '15 at 7:45
  • No, but something change, now the error repeats itself for every file: for f in *; do > mv "$f" $(echo "$f" | awk -F, '{OFS=",";gsub(/_/, ":", $NF)}1') > done awk: syntax error near line 1 awk: illegal statement near line 1 awk: syntax error near line 1 awk: bailing out near line 1 mv: Insufficient arguments (1) Usage: mv [-f] [-i] f1 f2 mv [-f] [-i] f1 ... fn d1 mv [-f] [-i] d1 d2 awk: syntax error near line 1 awk: illegal statement near line 1 awk: syntax error near line 1 awk: bailing out near line 1 mv: Insufficient arguments (1) ..... – Aitor Sep 22 '15 at 7:47
  • 1
    @Aitor I found the problem. The olf awk in solaris has no gsub() function. Please use nawk instead. – chaos Sep 22 '15 at 8:26
  • 1
    @Aitor see my edit – chaos Sep 22 '15 at 9:10

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.