bash - बाश में उनकी मूल निर्देशिका के आधार पर फ़ाइलें नाम बदलें




find rename (2)

इस कार्य के लिए पिछले कुछ पन्नों में एक साथ टुकड़े टुकड़े करने की कोशिश कर रहे थे। डायरेक्टरी ट्री इस तरह दिखती है:

TEST
   |ABC_12345678
       3_XYZ
   |ABC_23456789
       3_XYZ
   etc

"टेस्ट" नामक मूल फ़ोल्डर में प्रत्येक फ़ोल्डर हमेशा ABC_ \ d {8} के साथ शुरू होता है- 8 अंक हमेशा अलग होते हैं फ़ोल्डर के भीतर एबीसी_ \ d {8} हमेशा 3_XYZ नामक फ़ोल्डर होता है, जिसमें हमेशा "MD2_Phd.txt" नामक फाइल होती है। लक्ष्य प्रत्येक "MD2_PhD.txt" फ़ाइल का नाम बदलने के लिए है, जिसमें एबीसी फ़ोल्डर नाम "8

विभिन्न पदों से कोड के विभिन्न बिट्स पर कई पुनरावृत्तियों के बाद यह सबसे अच्छा है जिसके साथ मैं आ सकता हूं,

cd /home/etc/Desktop/etc/TEST
find -type d -name 'ABC_(\d{8})' |
find $d -name "*_PhD.txt" -execdir rename 's/MD2$/$d/' "{}" \;
done

+ bash समाधान find :

find -type f -regextype posix-egrep -regex ".*/TEST/ABC_[0-9]{8}/3_XYZ/MD2_Phd\.txt" \
-exec bash -c 'abc="${0%/*/*}"; fp="${0%/*}/";
 mv "$0" "$fp${abc##*_}_PhD.txt" ' {} \;

परिणाम देख रहे हैं:

$ tree TEST/ABC_*
TEST/ABC_12345678
└── 3_XYZ
    └── 12345678_PhD.txt
TEST/ABC_1234ss5678
└── 3_XYZ
    └── MD2_Phd.txt
TEST/ABC_23456789
└── 3_XYZ
    └── 23456789_PhD.txt

आप पाइप आउट आउटपुट को find लिए find यह काम नहीं करेगा

इसके बजाय एक पाश का प्रयोग करें:

dir_re='^.+_([[:digit:]]{8})/'
for file in *_????????/3_XYZ/MD2_PhD.txt; do
  [[ -f $file ]] || continue
  if [[ $file =~ $dir_re ]]; then
    dir_num="${BASH_REMATCH[1]}"
    new_name="${file%MD2_PhD.txt/$dir_num.txt}" # replace the MD2_PhD at the end
    echo mv "$file" "$new_name"                 # remove echo from here once tested
  fi
done




rename