फ़ाइल नाम के अंत में संशोधित टाइमस्टैम्प के साथ फ़ाइलों का एक समूह का नाम बदलना?


14

तो, कहते हैं, मेरे पास g.txt जैसी फ़ाइलों का एक समूह है, जहाँ g.txt को अंतिम बार संशोधित किया गया था, कहते हैं, 20 जून, 2012।

मैं 20 जून 2012 की अंतिम संशोधित तिथि के साथ सभी फ़ाइलों (जैसे g.txt) का नाम कैसे बदल दूंगा?

जवाबों:


13

क्विक-एंड-डर्टी बैश वन-लाइनर को मौजूदा निर्देशिका में सभी (ग्लोब्ड) फ़ाइलों का नाम बदलने के filename.txtलिए filename.txt-20120620:

for f in *; do mv -- "$f" "$f-$(stat -c %Y "$f" | date +%Y%m%d)"; done

एक उद्यमी बश नर्ड को इसे तोड़ने के लिए कुछ किनारे मामले मिलेंगे, मुझे यकीन है। :)

जाहिर है, यह जांचने जैसी वांछनीय चीजें नहीं करता है कि क्या फ़ाइल में पहले से ही कुछ है जो अंत में एक तारीख की तरह दिखता है।


2
+1, अच्छा लग रहा है। mv के पहले arg के रूप में '-' का उपयोग करके आप इसे थोड़ा और मजबूत बना सकते हैं। '-'
कैस

5
यह किस तरह का dateकार्यान्वयन है? मेरा GNU dateइनपुट को संभालने के लिए प्रतीत नहीं होता है।
मैनटवर्क


2
@jgoldschrafe, क्या आप सुनिश्चित हैं कि कोड आपके लिए ठीक से काम करता है? pastebin.com/nNYubf3A
15

5
अच्छी पकड़ है। मेरी जीएनयू तिथि 8.13 स्टड से पढ़ने का समर्थन नहीं करती है। यह "-r" - जैसे "तारीख +% Y% m% d -r $ f" के साथ फ़ाइल के मॉड समय का उपयोग करने का समर्थन करता है, इसलिए इस विशेष मामले में भी स्टेट की आवश्यकता नहीं है।
कैस

18

यहाँ सुनार की एक लाइनर का एक संस्करण है:

  • स्टेट का उपयोग नहीं करता है
  • GNU तिथि के पूर्व संस्करणों के साथ काम करता है
  • सही ढंग से फ़ाइल नाम में किसी भी स्थान के साथ मुकाबला करता है
  • यह भी एक डैश के साथ शुरुआत फ़ाइल नाम के साथ मुकाबला करता है

    for f in *; do mv -- "$f" "$f-$(date -r "$f" +%Y%m%d)"; done


1
आप इसे बनाना चाहिए date -r "$f" +%Y%m%dया यह काम नहीं करेगा अगर POSIXLY_CORRECTपर्यावरण में है। आमतौर पर, विकल्पों को अन्य तर्कों से पहले जाना चाहिए।
स्टीफन चेज़लस

यह "सही उत्तर" होना चाहिए
अमान्य

बेशक आप ब्रेसिज़ की जरूरत नहीं है "${f}"
जी-मैन का कहना है कि 'मोनिका'

लेकिन आप इसे ऐसे कैसे बनाएंगे कि हम पहले से मौजूद तारीखों जैसे "यम-फाइलन"?
टाइमबैंड

2

ओब्लाइगेटरी ज़िश वन-लाइनर (वैकल्पिक घटकों के एक बार लोडिंग की गिनती नहीं):

zmodload zsh/stat
autoload -U zmv
zmv -n '(*)' '$1-$(stat -F %Y%m%d +mtime -- $1)'

हम मॉड्यूलstat से बिलिन का उपयोग करते हैं , और फ़ाइलों का नाम बदलने के लिए फ़ंक्शन। और यहां एक अतिरिक्त है जो एक्सटेंशन से पहले की तारीख को रखता है, यदि कोई हो।zsh/statzmv

zmv -n '(*)' '$1:r-$(stat -F %Y%m%d +mtime -- $1)${${1:e}:+.$1:e}'

1

जैसा कि मैंने समझा कि हम पहले से नहीं जानते कि संशोधन की तारीख क्या है। इसलिए हमें इसे प्रत्येक फ़ाइल से प्राप्त करने की आवश्यकता है, आउटपुट को प्रारूपित करें और प्रत्येक फ़ाइल को एक तरह से नाम बदलें ताकि इसमें फ़ाइल नाम में संशोधन की तारीख शामिल हो।

आप इस स्क्रिप्ट को "modif_date.sh" की तरह सहेज सकते हैं और इसे निष्पादन योग्य बना सकते हैं। हम इसे तर्क के रूप में लक्ष्य निर्देशिका के साथ लागू करते हैं:

modif_date.sh txt_collection

जहां "txt_collection" उस निर्देशिका का नाम है, जहां हमारे पास सभी फाइलें हैं जिनका हम नाम बदलना चाहते हैं।

#!/bin/sh

# Override any locale setting to get known month names
export LC_ALL=c
# First we check for the argument
if [ -z "$1" ]; then
    echo "Usage: $0 directory"
    exit 1
fi

# Here we check if the argument is an absolute or relative path. It works both ways
case "${1}" in
  /*) work_dir=${1};;
  *) work_dir=${PWD}/${1};;
esac

# We need a for loop to treat file by file inside our target directory
for i in *; do
    # If the modification date is in the same year, "ls -l" shows us the timestamp.
    # So in this case we use our current year. 
    test_year=`ls -Ggl "${work_dir}/${i}" | awk '{ print $6 }'`
    case ${test_year} in *:*) 
        modif_year=`date '+%Y'`
        ;;
    *)
        modif_year=${test_year}
        ;;
    esac
    # The month output from "ls -l" is in short names. We convert it to numbers.
    name_month=`ls -Ggl "${work_dir}/${i}" | awk '{ print $4 }'`
    case ${name_month} in
            Jan) num_month=01 ;;
            Feb) num_month=02 ;;
        Mar) num_month=03 ;;
        Apr) num_month=04 ;;
        May) num_month=05 ;;
        Jun) num_month=06 ;;
        Jul) num_month=07 ;;
        Aug) num_month=08 ;;
        Sep) num_month=09 ;;
        Oct) num_month=10 ;;
        Nov) num_month=11 ;;
        Dec) num_month=12 ;;
        *) echo "ERROR!"; exit 1 ;;
    esac
    # Here is the date we will use for each file
    modif_date=`ls -Ggl "${work_dir}/${i}" | awk '{ print $5 }'`${num_month}${modif_year}
    # And finally, here we actually rename each file to include
    # the last modification date as part of the filename.
    mv "${work_dir}/${i}" "${work_dir}/${i}-${modif_date}"
done

1
स्टेट के लिए मैन पेज पढ़ें (1) यह जानने के लिए कि आप अपनी स्क्रिप्ट को लगभग 3/4 तक कैसे सिकोड़ सकते हैं ... सबसे ऊपर पहिया का फिर से आविष्कार कर रहा है। विशेष रूप से, 'स्टेट -c% Y' आपको युग (1970-01-01 00:00:00) के बाद से सेकंड में एक फ़ाइल का संशोधन समय देगा। इसके बाद टाइमस्टैम्प को आवश्यकतानुसार प्रारूपित करने के लिए तिथि (1) के इनपुट के रूप में उपयोग किया जा सकता है। एक उदाहरण के लिए ऊपर jgoldschrafe का उत्तर देखें।
कैस

@ क्रेगसैंडर्स उल्टा यह है कि यह स्क्रिप्ट लिनक्स के अलावा अन्य ऑपरेटिंग सिस्टम के तहत काम करती है, जिनकी एक अलग statउपयोगिता है या कोई भी नहीं है।
गिल्स एसओ- बुराई को रोकें '

ध्यान दें कि का आउटपुट पार्स करना lsविश्वसनीय नहीं है । कुछ यूनिक्स वेरिएंट पर, उपयोगकर्ता और समूह के नाम में रिक्त स्थान हो सकते हैं, जो दिनांक कॉलम के संरेखण को फेंक देगा।
गिल्स एसओ- बुराई को रोकें '

@giles: सच है, लेकिन कोई भी समझदार :-) किसी भी गैर-लिनक्स सिस्टम पर GNU कोरुटिल (और अन्य सभी GNU टूल्स) स्थापित करेगा। यह न केवल उपयोगकर्ता का एक अच्छा सेट प्राप्त करने का सबसे आसान तरीका है, बल्कि अंतर्निहित कर्नेल की परवाह किए बिना एक सुसंगत सेट भी है।
कैस

1
(Cont'd)… (5) एक और बग: यह मानता है कि किसी भी तारीख / समय के ls रूप में प्रदर्शित होने वाली तारीख / समय (तारीख और साल के बजाय) वर्तमान वर्ष में होना चाहिए। यह सच नहीं है। यह पिछले छह महीनों में है; यह पूर्व वर्ष में हो सकता है (उदाहरण के लिए, ३१-दिसंबर २०१६ से २ be-सितम्बर -२०१६ पिछले छह महीनों के भीतर)। (६) ग्रेग के विकी (जो @Gilles पहले ही उद्धृत किया गया है) को तोता करने के जोखिम में , जिन फ़ाइलनामों में newline (s) और रिक्त स्थान होते हैं, वे विफल हो सकते हैं। … (Cont'd)
G-Man कहते हैं मोनिका '

0

यहाँ cas के oneliner के संस्करण, (goldschrafe के oneliner के आधार पर) है के साथ बढ़ाया idempotence ,

यानी तारीख के समय के साथ उपसर्ग फ़ाइलों तक बढ़ाया गया है और ऐसा केवल उन लोगों के लिए किया गया है जिनके पास अभी तक समय उपसर्ग नहीं है

उपयोग-मामला: यदि आप डायरेक्टरी में नई फाइलें जोड़ते हैं तो मददगार होते हैं और जो अभी तक एक नहीं हैं, उनमें डेट टाइम उपसर्ग जोड़ना चाहते हैं।

for f in * ; do
  if [[ "$f" != ????-??-??' '??:??:??' - '* ]]; then
    mv -v -- "$f" "$(date -r "$f" +%Y-%m-%d' '%H:%M:%S) - $f" ;
  fi;
done

यदि आपकी फ़ाइलें टाइमस्टैम्प खराब हो गई हैं और जेपीजी हैं, तो आप उन्हें EXIF ​​डेटा के साथ ठीक करने के लिए एफआईआर कर सकते हैं: for f in *.jpg ; do jhead -ft "$f" ; doneस्रोत: unix.stackexchange.com/a/290755/9689
Grzegorz Wierziecki
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.