The new forums will be named Coin Return (based on the most recent vote)! You can check on the status and timeline of the transition to the new forums here.
The Guiding Principles and New Rules document is now in effect.

Linux: update last-mod time of directories?

mspencermspencer PAX [ENFORCER]Council Bluffs, IARegistered User regular
edited January 2007 in Help / Advice Forum
I have a Linux machine with a large number of files in a huge directory tree, saved from another machine. The original files aren't available any longer.

Both files and directories have a last-modified time. You can see that a certain file was last modified in April 2004, or Jan 2001, etc. Directories also have last-modified times, which usually correspond with the date and time the most recent modification happened.

I have a problem with these directories I saved. The files I saved each have the correct modification date. The directories the files live in, though, all have the same timestamp, which is the day I saved all the files. It's difficult to sort through all those files chronologically if all the directories have the same modification date.

Does anyone know of a way to update a directories last-modification date to match the date of the most recent file in the directory? I know you can use 'touch' to set a date to 'now', so if I wanted to move the clock forward I could. Is there a way to move backward?

(Yes I have root on this box, so I can do any weird filesystem manipulation necessary. I suppose I could learn how to do this stuff with system calls and write my own program, but I've never done this before.)

I'm thinking either there's a program someone wrote (that I can't find, on freshmeat or sourceforge) or there's a built-in system tool I can use with a command line 'for' statement.

Anybody have any hints?

MEMBER OF THE PARANOIA GM GUILD
XBL Michael Spencer || Wii 6007 6812 1605 7315 || PSN MichaelSpencerJr || Steam Michael_Spencer || Ham NOØK
QRZ || My last known GPS coordinates: FindU or APRS.fi (Car antenna feed line busted -- no ham radio for me X__X )
mspencer on

Posts

  • DrFrylockDrFrylock Registered User regular
    edited January 2007
    In general, touch has a switch that allows you to specify a different time.

    On my Ubuntu box, man time says:

    -t STAMP
    use [[CC]YY]MMDDhhmm[.ss] instead of current time

    Also:

    -r, --reference=FILE
    use this file's times instead of current time

    DrFrylock on
  • mspencermspencer PAX [ENFORCER] Council Bluffs, IARegistered User regular
    edited January 2007
    Thanks -- I think I can do something with that.

    Let's not call this solved yet. I'm trying to come up with a series of bash commands that set the timestamp of a directory to the time of each of the files inside the directory. Many directories contain other directories, though, so we'd need to set the time of the deepest directories first, then the second deepest, etc. This directory tree is nine levels deep.

    Since I don't think you can do recursion with bash commands, I'm working on a set of bash for statements that recurses into the deepest directories first, then the second deepest, etc. I'll post my statements if I can get this to work -- then we'll call this solved.

    Not yet though.

    mspencer on
    MEMBER OF THE PARANOIA GM GUILD
    XBL Michael Spencer || Wii 6007 6812 1605 7315 || PSN MichaelSpencerJr || Steam Michael_Spencer || Ham NOØK
    QRZ || My last known GPS coordinates: FindU or APRS.fi (Car antenna feed line busted -- no ham radio for me X__X )
  • ecco the dolphinecco the dolphin Registered User regular
    edited January 2007
    mspencer wrote:
    Since I don't think you can do recursion with bash commands, I'm working on a set of bash for statements that recurses into the deepest directories first, then the second deepest, etc. I'll post my statements if I can get this to work -- then we'll call this solved.

    I'm not quite sure what you mean by not being able to do recursion with bash commands, but is this what you meant?
    #!/bin/sh
    
    recursionFunction()
    {
      echo "This is level $1"
    
      if [ "$1" -lt "9" ]; then
        recursionFunction $(($1+1))
      fi
    }
    
    recursionFunction 1
    

    EDIT: Need to enable bbcode

    ecco the dolphin on
    Penny Arcade Developers at PADev.net.
  • mspencermspencer PAX [ENFORCER] Council Bluffs, IARegistered User regular
    edited January 2007
    I've got a solution now. It's sub-optimal but it's a solution.
    for a in */; do if test "$a" != '*/'; then \
     cd "$a"; for b in */; do if test "$b" != '*/'; then \
      cd "$b"; for c in */; do if test "$c" != '*/'; then \
       cd "$c"; for d in */; do if test "$d" != '*/'; then \
        cd "$d"; for e in */; do if test "$e" != '*/'; then \
         cd "$e"; for f in */; do if test "$f" != '*/'; then \
          cd "$f"; for g in */; do if test "$g" != '*/'; then \
           cd "$g"; for h in */; do if test "$h" != '*/'; then \
            cd "$h"; for i in *; do export x=$i; done; touch -r "$x" .; \
           cd ..; fi; done; \
          cd ..; fi; done; \
         cd ..; fi; done; \
        cd ..; fi; done; \
       cd ..; fi; done; \
      cd ..; fi; done; \
     cd ..; fi; done; \
    cd ..; fi; done
    
    
    for a in */; do if test "$a" != '*/'; then \
     cd "$a"; for b in */; do if test "$b" != '*/'; then \
      cd "$b"; for c in */; do if test "$c" != '*/'; then \
       cd "$c"; for d in */; do if test "$d" != '*/'; then \
        cd "$d"; for e in */; do if test "$e" != '*/'; then \
         cd "$e"; for f in */; do if test "$f" != '*/'; then \
          cd "$f"; for g in */; do if test "$g" != '*/'; then \
           cd "$g"; for h in *; do export x=$h; done; touch -r "$x" .; \
          cd ..; fi; done; \
         cd ..; fi; done; \
        cd ..; fi; done; \
       cd ..; fi; done; \
      cd ..; fi; done; \
     cd ..; fi; done; \
    cd ..; fi; done
    
    for a in */; do if test "$a" != '*/'; then \
     cd "$a"; for b in */; do if test "$b" != '*/'; then \
      cd "$b"; for c in */; do if test "$c" != '*/'; then \
       cd "$c"; for d in */; do if test "$d" != '*/'; then \
        cd "$d"; for e in */; do if test "$e" != '*/'; then \
         cd "$e"; for f in */; do if test "$f" != '*/'; then \
          cd "$f"; for g in *; do export x=$g; done; touch -r "$x" .; \
         cd ..; fi; done; \
        cd ..; fi; done; \
       cd ..; fi; done; \
      cd ..; fi; done; \
     cd ..; fi; done; \
    cd ..; fi; done
    
    for a in */; do if test "$a" != '*/'; then \
     cd "$a"; for b in */; do if test "$b" != '*/'; then \
      cd "$b"; for c in */; do if test "$c" != '*/'; then \
       cd "$c"; for d in */; do if test "$d" != '*/'; then \
        cd "$d"; for e in */; do if test "$e" != '*/'; then \
         cd "$e"; for f in *; do export x=$f; done; touch -r "$x" .; \
        cd ..; fi; done; \
       cd ..; fi; done; \
      cd ..; fi; done; \
     cd ..; fi; done; \
    cd ..; fi; done
    
    for a in */; do if test "$a" != '*/'; then \
     cd "$a"; for b in */; do if test "$b" != '*/'; then \
      cd "$b"; for c in */; do if test "$c" != '*/'; then \
       cd "$c"; for d in */; do if test "$d" != '*/'; then \
         cd "$d"; for e in *; do export x=$e; done; touch -r "$x" .; \
       cd ..; fi; done; \
      cd ..; fi; done; \
     cd ..; fi; done; \
    cd ..; fi; done
    
    for a in */; do if test "$a" != '*/'; then \
     cd "$a"; for b in */; do if test "$b" != '*/'; then \
      cd "$b"; for c in */; do if test "$c" != '*/'; then \
         cd "$c"; for d in *; do export x=$d; done; touch -r "$x" .; \
      cd ..; fi; done; \
     cd ..; fi; done; \
    cd ..; fi; done
    
    for a in */; do if test "$a" != '*/'; then \
     cd "$a"; for b in */; do if test "$b" != '*/'; then \
         cd "$b"; for c in *; do export x=$c; done; touch -r "$x" .; \
     cd ..; fi; done; \
    cd ..; fi; done
    
    for a in */; do if test "$a" != '*/'; then \
         cd "$a"; for b in *; do export x=$b; done; touch -r "$x" .; \
    cd ..; fi; done
    
    This way it's setting the timestamp of the directory to the time of the last file in that directory. I'd rather it set the timestamp of the directory to the latest time of all files in that directory.

    mspencer on
    MEMBER OF THE PARANOIA GM GUILD
    XBL Michael Spencer || Wii 6007 6812 1605 7315 || PSN MichaelSpencerJr || Steam Michael_Spencer || Ham NOØK
    QRZ || My last known GPS coordinates: FindU or APRS.fi (Car antenna feed line busted -- no ham radio for me X__X )
  • vonPoonBurGervonPoonBurGer Registered User regular
    edited January 2007
    mspencer wrote:
    repetitive wall of text
    
    Jesus dude. A recursive function would have saved you a lot of typing.

    vonPoonBurGer on
    Xbox Live:vonPoon | PSN: vonPoon | Steam: vonPoonBurGer
  • mspencermspencer PAX [ENFORCER] Council Bluffs, IARegistered User regular
    edited January 2007
    mspencer wrote:
    repetitive wall of text
    
    Jesus dude. A recursive function would have saved you a lot of typing.
    Copy and paste saved me a lot of typing.

    mspencer on
    MEMBER OF THE PARANOIA GM GUILD
    XBL Michael Spencer || Wii 6007 6812 1605 7315 || PSN MichaelSpencerJr || Steam Michael_Spencer || Ham NOØK
    QRZ || My last known GPS coordinates: FindU or APRS.fi (Car antenna feed line busted -- no ham radio for me X__X )
Sign In or Register to comment.