LinuxQuestions.org
Visit Jeremy's Blog.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 12-06-2011, 08:16 PM   #1
Liquid_Squelch
LQ Newbie
 
Registered: May 2006
Location: Long Island, NY
Distribution: Suse 12.2
Posts: 12

Rep: Reputation: 0
Using BASH to Rename files with last mod date using stat & awk


I've seen solutions for this question before, but for whatever reason, I'm not able to get it to work on my opensuse machine.

I have a directory of files (website daily backup) that I want to rename with their create (modified) date and save them off to a new directory.

The new directory has the base file name, and for now, that step has been removed from the script.

Basically, take the file which will be called via a variable on the command line, find the modified date, and rename the file to include the modified date as part of the file name.

The code I have is below. I can get the base file name, but my mod_date does not return anything, so I get files saved as "base_.ext"

Any one have any solutions? The file I am trying to rename does exist. I did a 'touch filename.tst' to create "filename.tst"
Thanks

commandline to launch would be: ./rename.sh file

Code:
#!/bin/bash

# Backup with stat date

# File prefix
file=${1}

# Rename the file with the modified date
stat -c %y ${file}.tst | mod_date="awk '{print $1}'" | cp ${file}.tst ${file}_${mod_date}.txt ;
 
Click here to see the post LQ members have rated as the most helpful post in this thread.
Old 12-07-2011, 03:27 AM   #2
Chirel
Member
 
Registered: Nov 2009
Posts: 55

Rep: Reputation: 19
Hi,

When you do

Code:
# Rename the file with the modified date
stat -c %y ${file}.tst | mod_date="awk '{print $1}'" | cp ${file}.tst ${file}_${mod_date}.txt ;
I guess what you really want is to do that :

Code:
# Copy the file with the modified date
mod_date="$(stat -c %y ${file}.tst | awk '{print $1}')"
cp ${file}.tst ${file}_${mod_date}.txt
Then use mv when you are ready.
 
1 members found this post helpful.
Old 12-07-2011, 01:52 PM   #3
Reuti
Senior Member
 
Registered: Dec 2004
Location: Marburg, Germany
Distribution: openSUSE 11.4
Posts: 1,319

Rep: Reputation: 252Reputation: 252Reputation: 252
Quote:
Originally Posted by Chirel View Post
Code:
# Copy the file with the modified date
mod_date="$(stat -c %y ${file}.tst | awk '{print $1}')"
cp ${file}.tst ${file}_${mod_date}.txt
As the mod_date is an assigned variable, it should be possible to strip off the unwanted information by bash’s parameter expansion:
Code:
# Copy the file with the modified date
mod_date=$(stat -c %y ${file}.tst)
cp ${file}.tst ${file}_${mod_date%% *}.txt
Or assign it to an array and use the first element as it’s split by a space character already:
Code:
# Copy the file with the modified date
mod_date=($(stat -c %y ${file}.tst))
cp ${file}.tst ${file}_${mod_date}.txt

Last edited by Reuti; 12-12-2011 at 04:24 AM. Reason: Typo
 
1 members found this post helpful.
Old 12-07-2011, 04:45 PM   #4
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,823

Rep: Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946
Code:
stat -c %y ${file}.tst | mod_date="awk '{print $1}'" | cp ${file}.tst ${file}_${mod_date}.txt ;
Chirel has already showed the correct way to write this, but I'm going to explain why.

The "|" pipe feeds the stdout of one command into the stdin of the next. This means you need to make sure that the commands you use write & read to each other properly.

The stat command at the beginning is ok. It sends its output to stdout. But looking at the second command...

Code:
mod_date="awk '{print $1}'"
While awk does read from stdin, you aren't actually running awk here. All you're doing is setting the variable "mod_date" to the literal string "awk '{print $1}'".

So there's no command here that reads from stdin.

To set a variable from a command you need to use a command substitution, which is "$()"
Code:
stat -c %y ${file}.tst | mod_date=$( awk '{print $1}' )
That's a little better, but now we have a problem in that commands in pipes run as subshells. Variables are only available inside the shells they are set in (and child processes of the same), and so mod_date is lost as soon as the command terminates.

But we don't really want to set a variable yet anyway. If we capture the output to a variable, then there's nothing for the next command in the chain to read. So lets remove that and just use awk directly.

Code:
stat -c %y ${file}.tst | awk '{print $1}'
awk now prints to stdout, which becomes the stdin of the next command. However...

Code:
cp ${file}.tst ${file}_${mod_date}.txt
cp is not a command capable of reading from stdin, so it just ignores the input from the rest of the chain. And we don't have a mod_date variable to use anyway, so the command fails. So what do we do?

Well, we capture the output of the stat+awk chain as a whole into a variable, then we subsequently run cp using it. And that's the solution what Chirel supplied.


Finally, as Reuti demonstrated, It's possible to replace awk with bash's built-in parameter substitution.


I advise you to take some time and read through the Bash Guide here before continuing on. It covers all the basic concepts you need to know:

http://mywiki.wooledge.org/BashGuide

The FAQ and Pitfalls pages in particular are also extremely useful:

http://mywiki.wooledge.org/BashFAQ
http://mywiki.wooledge.org/BashPitfalls
 
2 members found this post helpful.
Old 12-11-2011, 06:27 PM   #5
Liquid_Squelch
LQ Newbie
 
Registered: May 2006
Location: Long Island, NY
Distribution: Suse 12.2
Posts: 12

Original Poster
Rep: Reputation: 0
Thank you all for the help. The solutions offered helped - and I certainly appreciate the explanation from David the H. It is one thing to copy an answer into the script (which works), but it is another to understand how and why it works.

Thanks again to all who replied..
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Rename files using csv file and awk tuxlux Programming 6 09-03-2013 07:46 PM
Application to eliminate doubles in files and rename changed files with date? S. Chapelin Linux - Software 6 01-16-2011 02:02 AM
[SOLVED] BASH: Keep original mod date of a file and 'date' it back to same file? SilversleevesX Programming 4 07-16-2010 11:12 AM
Rename Files With Date Picture Taken On Command lonecrow Linux - General 1 10-30-2006 12:18 PM
awk cli to rename a list of files... pld Linux - General 4 02-15-2005 10:57 PM


All times are GMT -5. The time now is 09:02 PM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration