LinuxQuestions.org
Visit the LQ Articles and Editorials section
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 07-29-2011, 12:14 PM   #1
pjgm
LQ Newbie
 
Registered: Jul 2011
Posts: 17

Rep: Reputation: Disabled
Question [SOLVED] Bash Script to Copy Modification Date from a file to his folder


Hi There,

I need this script but I don't know how to do it

I have one folder with several folders inside.

On each folder a have one MKV or AVI file inside...

What I need is a script to change the "modification date" of each folder to the "modification date" of each MKV or AVI that the folder has inside.

Cheers
PJGM

PS: My system: NAS with Linux 2.6.24.4

Last edited by pjgm; 08-24-2011 at 09:49 AM.
 
Click here to see the post LQ members have rated as the most helpful post in this thread.
Old 07-29-2011, 12:35 PM   #2
colucix
Moderator
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,508

Rep: Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957
Code:
while read file
do
  touch -t $(date -r "$file" +%Y%m%d%H%M) "$(dirname "$file")"
done < <(find . \( -iname \*.avi -o -iname \*.mkv \))

Last edited by colucix; 07-30-2011 at 02:48 AM. Reason: added double quotes to manage directories with blank spaces
 
Old 07-29-2011, 12:36 PM   #3
MensaWater
Guru
 
Registered: May 2005
Location: Atlanta Georgia USA
Distribution: Redhat (RHEL), CentOS, Fedora, Debian, FreeBSD, HP-UX, Solaris, SCO
Posts: 6,014
Blog Entries: 5

Rep: Reputation: 787Reputation: 787Reputation: 787Reputation: 787Reputation: 787Reputation: 787Reputation: 787
You can use the "touch" command to change dates including modifications dates (-m option to change only modification date).

Type "man touch" for more detail on the touch command.

Generally doing "touch -m CCYYMMDD <filename>" would do what you want for the filename (including a directory filename).
e.g.
touch -m 20110630 testdir
Would put the date Jun 30 2011 on the directory named testir.

touch -m 20060512 test.avi
Would put the date May 12 2006 on the file test.avi.

You can use the "ls -l -time-style +%Y%m%d <filename>" to list a file with its date in the same format as above. (Type "man ls" for more detail on the ls command.

You'd want to do a for loop to do what you're asking (or what I think you're asking). Something like:
Code:
cd <mainfolder>
for folder in $(ls -d *)
do touchtm=$(ls -l -time-style +%Y%m%d $folder/* |awk '{print $6}')
   touch $touchtm $folder
done
You'd substitute your parent folder for what I show as <mainfolder> above. Note the above scripts assumes there is only one file in each of your subdirectories. You'd have to figure out a file specification if there were more (e.g. if you had dozens of files but only one file with a .avi suffix in each directory you could use "*.avi).

The awk command above just gets the 6th position from the ls output and that is the position that has the date of the file. (You can type "man awk" for more detail - awk is a full text/programming utility so it is often best to find a good tutorial for it for more advanced usage - there are many on the internet.)

Prior to trying this in your real directory you might want to make a test directory as your main folder then copy a couple of the subdirectories and their contents to it to be sure the loop works the way you want.
 
2 members found this post helpful.
Old 07-29-2011, 12:44 PM   #4
Diantre
Member
 
Registered: Jun 2011
Distribution: Slackware
Posts: 390

Rep: Reputation: 152Reputation: 152
Well, here's another one:

Code:
#!/bin/bash

for i in *; do
    if [[ -d $i ]]; then
        moddate=$(stat -c %y "$i")
        touch -m -c -d "$moddate" "$i/*.mkv" "$i/*.avi"
    fi
done
Run it from the main directory with subdirs containing videos.

Last edited by Diantre; 07-29-2011 at 12:56 PM. Reason: Adding double quotes to variables...
 
Old 07-29-2011, 12:55 PM   #5
colucix
Moderator
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,508

Rep: Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957
Quote:
Originally Posted by Diantre View Post
Well, here's another one:

Code:
#!/bin/bash

for i in *; do
    if [[ -d $i ]]; then
        moddate=$(stat -c %y $i)
        touch -m -c -d "$moddate" $i/*.mkv $i/*.avi
    fi
done
Run it from the main directory with subdirs containing videos.
I think the problem is the opposite here. The modification time of the directories should be changed, not the modification time of the files inside them.
 
Old 07-29-2011, 01:44 PM   #6
Diantre
Member
 
Registered: Jun 2011
Distribution: Slackware
Posts: 390

Rep: Reputation: 152Reputation: 152
Quote:
Originally Posted by colucix View Post
I think the problem is the opposite here. The modification time of the directories should be changed, not the modification time of the files inside them.
Oh my! I misread the original post. I suppose my brain is working backwards today. Thank you for your correction, and please disregard my post!
 
Old 07-29-2011, 03:06 PM   #7
pjgm
LQ Newbie
 
Registered: Jul 2011
Posts: 17

Original Poster
Rep: Reputation: Disabled
wooow Thank you guys !!!

I'm trying but when I run this:

Quote:
#!/bin/bash
cd /home/Public/Concertos
for folder in $(ls -d *)
do touchtm=$(ls -l -time-style +%Y%m%d $folder/* |awk '{print $6}')
touch $touchtm $folder
done
I get

Quote:
ls: invalid option -- e
thanks
pjgm

Last edited by pjgm; 07-29-2011 at 04:14 PM.
 
Old 07-29-2011, 03:48 PM   #8
colucix
Moderator
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,508

Rep: Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957
It should be --time-style (double hyphen). In any case there are valid reasons why using ls in a for loop is not a good idea.
 
Old 07-29-2011, 04:25 PM   #9
pjgm
LQ Newbie
 
Registered: Jul 2011
Posts: 17

Original Poster
Rep: Reputation: Disabled
sorry both doesn't work for me...

just to be more clear...

Giving the same modification date of Movies.mkv to their parent directory

-Movies folder # script should work on every folders on this directory
---- Movie name A folder # This folder should get...
-------- Movie name A.mkv # ...this modification date
-------- movie name A.nfo
---- Movie name B folder # This folder should get...
-------- Movie name B.mkv # ...this modification date
-------- movie name B.nfo
---- Movie name C folder # This folder should get...
-------- Movie name C.mkv # ...this modification date
-------- movie name C.nfo

and just a small note: 'movie A.mkv' can have a different name than the 'Movie A folder'

Last edited by pjgm; 07-29-2011 at 04:52 PM.
 
Old 07-29-2011, 07:11 PM   #10
Diantre
Member
 
Registered: Jun 2011
Distribution: Slackware
Posts: 390

Rep: Reputation: 152Reputation: 152
pjgm, my apologies for misreading your question and posting the opposite solution. I believe this script does what you require:

Code:
#!/bin/bash

for i in *; do
    if [[ -d $i ]]; then
        # list the first .mkv file in the directory
        movie=$(ls -1 $i/*.mkv | head -1)
        # if a .mkv file was found
        if [[ -f $movie ]]; then
            # get it's modification date
            moddate=$(stat -c %y $movie)
            # and apply it to the folder
            touch -d "$moddate" "$i"
        fi
    fi
done
 
Old 07-30-2011, 02:50 AM   #11
colucix
Moderator
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,508

Rep: Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957
I've tried my code on your directory structure and it works now, with a minor modification to manage the blank spaces in the directory names:
Code:
while read file
do
  touch -t $(date -r "$file" +%Y%m%d%H%M) "$(dirname "$file")"
done < <(find . \( -iname \*.avi -o -iname \*.mkv \))
 
Old 07-30-2011, 02:29 PM   #12
pjgm
LQ Newbie
 
Registered: Jul 2011
Posts: 17

Original Poster
Rep: Reputation: Disabled
I thank you all

A friend of mine gave me this...

credits to him... Vpeter

Quote:
#!/bin/bash
#
# fix movie folder date
# by vpeter for pjgm
#
# ref
# http://unix.stackexchange.com/questi...ps-recursively
#

# find folders in curent folder
find -mindepth 1 -maxdepth 1 -type d | while read dir ; do
echo -n "Modifying date '$dir' "
# go down
cd "$dir"
# get reference file date
#refFile=$(find -mindepth 1 -maxdepth 1 \( -name "*.avi" -o -name "*.mkv" \) -printf '%T+=%p\n' | sort -n | tail -n 1 | sed 's/[^=]*=//')
# first find .avi file
refFile=$(find -mindepth 1 -maxdepth 1 -name '*.avi' -printf '%T+=%p\n' | sort -n | tail -n 1 | sed 's/[^=]*=//')
if [ ! -n "$refFile" ]; then
# then find .mkv file
refFile=$(find -mindepth 1 -maxdepth 1 -name '*.mkv' -printf '%T+=%p\n' | sort -n | tail -n 1 | sed 's/[^=]*=//')
fi
# file set
if [ ! -n "$refFile" ]; then
echo " - no reference .avi|.mkv file found"
else
echo "using file '$refFile'"
# set date first on folder
touch -r "$refFile" .
# set date on all the other files too
touch -r "$refFile" *
fi
# go up
cd ..
done
thanks again for your time.
Pjgm
 
Old 07-31-2011, 08:33 AM   #13
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

Rep: Reputation: 942Reputation: 942Reputation: 942Reputation: 942Reputation: 942Reputation: 942Reputation: 942Reputation: 942
This should do the trick, if you use Bash:
Code:
find ./ -depth -mindepth 1 -type f '(' -name '*.avi' -o -name '*.mkv' ')' -print0 \
| ( IFS=$'\0' ; while read -d "" FILE ; do echo touch -r "$FILE" "$(dirname "$FILE")" ; done )
The first line searches for such files in all subdirectories.
The second line uses touch to set the modification time on the parent directory to match each file found.

If you do not use Bash, or you have a non-GNU find, or old find, use
Code:
/bin/sh -c 'find ./ -type f | while read FILE ; do
    case "$FILE" in
        *.avi|*.mkv)
            ;;
        *) continue
            ;;
    esac
    touch -r "$FILE" "`dirname "$FILE"`"
done'
but note this will b0rk if the file names contain newlines. This latter should work with all POSIX and even some Bourne shells. On SunOS 5.10 (and other old OSes) you may need to replace the touch line with settime -r "$FILE" "`dirname "$FILE"`" to set the directory time.
 
  


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
Get file modification date/time in Bash script cmfarley19 Programming 12 01-19-2013 09:37 AM
copy all the files in the directory based on the modification date SriniKlr Programming 4 01-26-2011 10:08 AM
Bash Script - adding file modification date to end of filenames in directory themonkman Programming 2 09-01-2009 11:45 PM
Bash script to copy contents of folder brian.m Linux - General 8 05-01-2009 06:08 PM
copy folder/files according to modification date bkcreddy17 Programming 14 10-15-2008 07:24 PM


All times are GMT -5. The time now is 01:13 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