मैं फ़ोल्डर टाइमस्टैम्प को नवीनतम फ़ाइल में कैसे बदलूं?


16

मैं सोच रहा था कि क्या किसी को पता है कि फ़ोल्डर्स के टाइमस्टैम्प को फिर से कैसे बदलना है, उस फ़ोल्डर में फ़ाइलों के पाए जाने वाले नवीनतम टाइमस्टैम्प के आधार पर।

उदाहरण के लिए:

jon @ UbuntuPanther: / मीडिया / मीडिया / MP3s / फू फाइटर्स / (1997-05-20) रंग और आकार $ ls -alF
कुल 55220
drwxr-xr-x 2 jon jon 4096 2010-08-30 12:34/।
drwxr-xr-x 11 jon jon 4096 2010-08-30 12:34 ../
-rw-r - r-- 1 jon jon 1694044 2010-04-18 00:51 फू फाइटर्स - Doll.mp3
-rw-r - r-- 1 jon jon 3151170 2010-04-18 00:51 फू फाइटर्स - पर्याप्त जेट। Mp3
-rw-r - r-- 1 jon jon 5004289 2010-04-18 00:52 फ़ू फाइटर्स - Everlong.mp3
-rw-r - r-- 1 jon jon 5803125 2010-04-18 00:51 फू फाइटर्स - फरवरी सितारे। mp3
-rw-r - r-- 1 jon jon 4994903 2010-04-18 00:51 फू फाइटर्स - अरे, जॉनी पार्क ।mp3
-rw-r - r-- 1 jon jon 4649556 2010-04-18 00:52 फू फाइटर्स - मंकी रिंच। एमपी 3
-rw-r - r-- 1 jon jon 5216923 2010-04-18 00:51 फू फाइटर्स - मेरा हीरो.mp3
-rw-r - r-- 1 jon jon 4294291 2010-04-18 00:52 फू फाइटर्स - मेरा गरीब ब्रेन.mp3
-rw-r - r-- 1 jon jon 6778011 2010-04-18 00:52 फू फाइटर्स - न्यू वे होम। एमपी।
-rw-r - r-- 1 jon jon 2956287 2010-04-18 00:51 फू फाइटर्स - See you.mp3
-rw-r - r-- 1 jon jon 2730072 2010-04-18 00:51 फू फाइटर्स - अप्स इन आर्म्स एमपी।
-rw-r - r-- 1 jon jon 6086821 2010-04-18 00:51 फू फाइटर्स - आपके साथ चलना। एमपी 3
-rw-r - r-- 1 jon jon 3033660 2010-04-18 00:52 फू फाइटर्स - Wind Up.mp3

फ़ोल्डर "(1997-05-20) द कलर एंड द शेप" में इसका टाइमस्टैम्प सेट 2010-04-18 00:52 तक होगा।

जवाबों:


21

आप touch -rवर्तमान समय (या touch --reference=FILE) के बजाय किसी अन्य फ़ाइल के टाइमस्टैम्प का उपयोग करने के लिए उपयोग कर सकते हैं

यहाँ दो समाधान हैं। प्रत्येक समाधान में, पहला कमांड निर्देशिका के संशोधन समय को तुरंत उसके अंतर्गत सबसे नई फ़ाइल में बदल देता है, और दूसरा कमांड पूरी निर्देशिका ट्री को पुनरावर्ती रूप से देखता है। cd '.../(1997-05-20) The Colour and The Shape'किसी भी आदेश को चलाने से पहले निर्देशिका ( ) में बदलें ।

Zsh में ( Dडॉट फ़ाइलों को अनदेखा करने के लिए निकालें ):

touch -r *(Dom[1]) .
touch -r **/*(Dom[1]) .

लिनक्स पर (या सामान्यतः GNU खोज के साथ):

touch -r "$(find -mindepth 1 -maxdepth 1 -printf '%T+=%p\n' |
            sort |tail -n 1 | cut -d= -f2-)" .
touch -r "$(find -mindepth 1 -printf '%T+=%p\n' |
            sort |tail -n 1 | cut -d= -f2-)" .

हालांकि ध्यान दें कि वे लोग फ़ाइल नामों में कोई नई पंक्ति वर्ण नहीं मानते हैं।


कमांड काम करते हैं (मैंने लिनक्स वाले का उपयोग किया था) लेकिन यह पुनरावर्ती रूप से काम नहीं कर रहा है। मैंने इसे अपने मूल फ़ोल्डर (/ मीडिया / मीडिया / MP3s) में चलाया और बाकी कलाकार निर्देशिकाओं के साथ ऐसा कोई भाग्य नहीं था। अब तक आपकी मदद के लिए धन्यवाद।
मंकीवॉन्च 32

@ MonkeyWrench32: जैसे ही मैंने इसे समझा, मैंने आपके सवाल का जवाब दिया। क्या आप प्रत्येक निर्देशिका के नीचे कमांड लागू करना चाहते हैं /media/media/MP3s? Zsh में तब: for d in /media/media/MP3s/**/*(/); do touch -r $d/*(Dom[1]) $d; done। बिना zsh (लेकिन वास्तव में, zsh का उपयोग करें, यह सिर्फ सरल है): कमांड को स्क्रिप्ट में रखें और चलाएं find /media/media/MP3s -type d -execdir /path/to/the/script \;
गिल्स एसओ- बुराई को रोकें '

पूर्णता! आप एक zsh मास्टर हैं! : डी
मंकीवेंच 32

यदि आप उपयोग करते हैं तो आप for d in ...निम्नलिखित को कैसे अनुकूलित कर सकते हैं, इसलिए यह फ़ोल्डर्स के साथ भी काम करेगा, जिसमें रिक्त स्थान हैं? (जो मेरे समाधान में अभी भी गायब है)
rubo77

@ rubo77 मुझे समझ नहीं आ रहा है कि आप किस बारे में बात कर रहे हैं। मेरे द्वारा पोस्ट किए गए सभी समाधान रिक्त स्थान वाले फ़ाइल नामों पर काम करते हैं (उनमें से कुछ फ़ाइल नामों पर विफल होते हैं जिनमें नई सूचियाँ होती हैं)। ध्यान दें कि मेरे कुछ समाधानों के लिए zsh की आवश्यकता होती है, जिसमें चर प्रतिस्थापन के आसपास दोहरे उद्धरण चिह्नों की आवश्यकता नहीं होती है।
गिलेस एसओ- बुराई को रोकना '

3

यह "पुनरावर्ती" नहीं है, यह सिर्फ एक फ़ोल्डर में सभी टाइमस्टैम्प बदल रहा है। यदि आपका यही मतलब है, तो दो चरण हैं।

stat -c '%Y' filenameके टाइमस्टैम्प का उत्पादन करेगा filename, और stat -c '%Y %n' *फ़ोल्डर में हर फ़ाइल के टाइमस्टैम्प और फ़ाइलनाम का उत्पादन करेगा, इसलिए यह वर्तमान फ़ोल्डर में सबसे हाल ही में संशोधित फ़ाइल का फ़ाइल नाम मिलेगा:

mostrecent="`stat -c '%Y %n' * | sort -n | tail -n1 | cut -d ' ' -f '2-'`"

दूसरी सोचा पर, एक है जिस तरह से फ़ोल्डर में उच्चतम टाइमस्टैम्प प्राप्त करने के लिए आसान तरीका है:

mostrecent="`ls -t | head -n1`"

फिर आप फ़ोल्डर में सभी फ़ाइलों को उसी फ़ाइल के समान टाइमस्टैम्प में बदलना चाहते हैं। touch -r foo barके barरूप में एक ही संशोधित टाइमस्टैम्प के लिए fooबदल जाएगा, तो यह आपकी सबसे हाल ही में संशोधित फ़ाइल के रूप में एक ही संशोधित टाइमस्टैम्प होने के लिए फ़ोल्डर में सभी फ़ाइलों को बदल देगा:

touch -r "$mostrecent" *

तो, एक-लाइनर है:

touch -r "`ls -t | head -n1`" *

एलएस के आउटपुट को पार्स करना एक बुरा विचार है , हालांकि मैं मानता हूं कि यह एक आकर्षक मामला है। यदि अभी भी lsगैर-एएससीआईआई पात्रों के नाम दर्ज हैं तो यह जोखिम भरा है । अगर आप वन-लाइनर्स चाहते हैं, तो zsh :-)
गिल्स का SO- बुराई करना बंद करें '

@ गिल्स यह है, लेकिन मुझे अभी तक इसे करने में समस्या है; मुझे लगता है क्योंकि मेरे फ़ाइल नाम में गैर-ASCII वर्ण नहीं हैं। आपका जवाब हालांकि बेहतर है
माइकल Mrozek

2

मैंने काम को एक साथ रखा और अब:

यह एक स्क्रिप्ट होगी जो सभी निर्देशिकाओं /tmp/test/को प्रत्येक निर्देशिका के अंदर नवीनतम फ़ाइल के टाइमस्टैम्प में बदल देती है:

#!/bin/bash
if [ -z "$1" ] ; then
  echo 'ERROR: Parameter missing. specify the folder!'
  exit
fi
#MODE=tail # change to newest file
MODE=head # change to oldest file
for d in "$1"/*/; do
  echo "running on $d"
  find "$d" -type d -execdir \
    echo touch --reference="$(find "$d" -mindepth 1 -maxdepth 1 -printf '%T+=%p\n' \
                              | sort | "$MODE" -n 1 | cut -d= -f2-)" "$d" \;
    # remove echo to really run it
done

आप इस तरह से / tmp में कुछ परीक्षण फ़ाइलें जोड़ सकते हैं:

mkdir /tmp/test
cd /tmp/test
mkdir d1
mkdir d2
touch d1/text1.txt
sleep 1
touch d1/movie1.mov
touch d2/movie2.mov
sleep 1
touch d2/text2.txt
touch notthis.file


1
आपके संपादन के लिए धन्यवाद, यह काम करता है! हालांकि प्रतिध्वनि "फिर से हटाती है , यह पहले दिखता है, जैसे यह गायब है, लेकिन यह काम करता है।
रुबों 77


0

मैं इस स्क्रिप्ट का उपयोग नवीनतम सामग्री के लिए पुन: फ़ोल्डर टाइमस्टैम्प सेट करने के लिए करता हूं। (यह गिल्स के उत्तर के समान है):

#! /bin/bash

# Change mtime of directories to that of latest file (or dir) under it, recursively
# Empty leaf directories, or dirs with only symlinks get the $default_timestamp

default_timestamp='1980-01-01 00:00:00'

dir="$1"

[ -d "$dir" ] || { echo "Usage: $0 directory" >&2; exit 1; }

find "$dir" -depth -type d | while read d; do
    latest=$(find "$d" -mindepth 1 -maxdepth 1 \( -type f -o -type d \) -printf '%T@ %p\n' | sort -n | tail -1 | cut -d' ' -f2-)
    if [ -n "$latest" ]; then
        touch -c -m -r "$latest" "$d" \
            || echo "ERROR setting mtime of '$d' using ref='$f'" >&2
    else
        touch -c -m -d "$default_timestamp" "$d" \
            || echo "ERROR setting mtime of '$d' to default '$default_timestamp'" >&2
    fi
done

0

मैंने @Gilles zsh कमांड लिया है और इसे सबफ़ोल्डर में काम करने के लिए बढ़ाया है, लेकिन ऐसा लगता है कि zsh ** / * (FDod) भाग के लिए बहुत अक्षम है।

# Don't do this
for d in **/*(FDod); do touch -r "$d"/*(Dom[1]) "$d"; done

उद्धरण सही ढंग से काम करने के लिए रिक्त स्थान और टैब युक्त निर्देशिका प्रविष्टियों की अनुमति देते हैं। एफडी इसे गैर-खाली निर्देशिकाओं को खोजने के लिए बनाता है, जिसमें शुरुआत करने वाले लोग शामिल हैं।, ओआरडी इसे गहराई-पहले तरीके से खोजता है, ताकि मूल फ़ोल्डर टाइमस्टैम्प ठीक से अपडेट हो जाए।

परीक्षण करते समय, मैंने देखा कि ** / * (FDod) के लिए प्रदर्शन और मेमोरी पदचिह्न पागल था (केवल 650k फ़ोल्डरों के लिए 1.4GB से अधिक), और यह फ़ोल्डरों को छूने के लिए शुरू करने से पहले पूरा पढ़ा। इसे खोजने / पढ़ने के साथ बदलने के बाद यह बहुत तेज हो गया, मेमोरी बर्न नहीं की और लगभग सीधे शुरू कर दिया।

#! /usr/bin/env zsh
# Do this instead
find "$@" -depth -type d ! -empty -print0 |while IFS= read -r -d ''; do
    touch -r "$REPLY"/*(Dom[1]) "$REPLY"
done

यदि आप इसे स्क्रिप्ट में नहीं चला रहे हैं, तो "$ @" को उन फ़ोल्डरों से बदलें, जिन्हें आप इसे चलाना चाहते हैं।


-1

मैं वास्तव में शेल कमांड की अस्पष्टता को पसंद नहीं करता था और जल्दी से इसे अजगर में किया।

यह पुनरावर्ती सभी निर्देशिका mtimes को नवीनतम गैर-बहिष्कृत फ़ाइल / dir mtime के अंदर सेट करता है।

import os
import sys

EXCLUDE_FILES = ['.DS_Store']
EXCLUDE_DIRS = ['.git', '.hg']

def inheritMTime(path):
    for root, dirs, files in os.walk(path, topdown=False, followlinks=False):
        currentMaxMtime = None
        for subpath in files:
            if subpath in EXCLUDE_FILES:
                print "ignore file", os.path.join(root, subpath)
                continue
            currentMaxMtime = max(currentMaxMtime, os.lstat(os.path.join(root, subpath)).st_mtime)
        for subpath in dirs:
            if subpath in EXCLUDE_DIRS:
                print "ignore dir", os.path.join(root, subpath)
                continue
            currentMaxMtime = max(currentMaxMtime, os.lstat(os.path.join(root, subpath)).st_mtime)
        if currentMaxMtime is not None:
            os.utime(root, (currentMaxMtime, currentMaxMtime))

if __name__ == "__main__":
    for dir in os.listdir(sys.argv[1]):
        if os.path.isdir(dir):
            current = os.path.join(sys.argv[1], dir)
            inheritMTime(current)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.