আমি এজেড ফোল্ডারে তাদের ফাইলের নামের প্রথম অক্ষরের উপর ভিত্তি করে ফাইলগুলি কীভাবে সংগঠিত করতে পারি


15

আমি তাদের প্রথম চিঠির মাধ্যমে 1000 টিরও বেশি ফন্টের ব্যবস্থা করার জন্য একটি উপায় (পছন্দসই টার্মিনাল) সন্ধান করছি।

মূলত ডিরেক্টরিগুলি তৈরি করুন A-Z, #তারপরে হরফ ফাইলগুলিকে তাদের ফাইলের নামের প্রথম অক্ষরের উপর ভিত্তি করে সেই ডিরেক্টরিগুলিতে স্থানান্তর করুন। #ডিরেক্টরিতে স্থানান্তরিত করার জন্য [0-9] সংখ্যা বা অন্যান্য বিশেষ অক্ষর দিয়ে শুরু হওয়া ফন্টগুলি ।


সেই চিঠিটি দিয়ে কোনও ফাইল শুরু না করা সত্ত্বেও আপনি কি ডিরেক্টরিগুলি তৈরি করতে চান?
অ্যারোনিকাল

@ অ্যারোনিকাল নোপ শুধু যদি ফাইল আছে।
পার্তো

4
আমি আশা করি এই লিঙ্কটি আপনাকে স্ট্যাকওভারফ্লো.com
কার্তিক্কিয়ান

উত্তর:


13

দেরিতে পাইথন বিকল্প:

#!/usr/bin/env python3
import os
import sys
import shutil

def path(dr, f): return os.path.join(dr, f)

dr = sys.argv[1]
for f in os.listdir(dr):
    fsrc = path(dr, f)
    if os.path.isfile(fsrc):
        s = f[0]; target = path(dr, s.upper()) if s.isalpha() else path(dr, "#")
        if not os.path.exists(target):
            os.mkdir(target)
        shutil.move(fsrc, path(target, f))

কিভাবে ব্যবহার করে

  1. একটি ফাঁকা ফাইলে স্ক্রিপ্টটি অনুলিপি করুন, এটি সংরক্ষণ করুন move_files.py
  2. এটি যুক্তি হিসাবে ডিরেক্টরি দিয়ে চালান:

    python3 /path/to/move_files.py /path/to/files
    

স্ক্রিপ্টটি কেবলমাত্র (সাব) ডিরেক্টরি (-ies) (বড় হাতের অক্ষর) তৈরি করবে যদি এটি প্রকৃত প্রয়োজন হয়

ব্যাখ্যা

এই পান্ডুলিপি:

  • ফাইলগুলি তালিকাভুক্ত করে, প্রথম অক্ষর পায় (স্যুরসেপথ সংজ্ঞায়িত করে):

    for f in os.listdir(dr):
        s = f[0]; fsrc = path(dr, f)
  • আইটেমটি কোনও ফাইল কিনা তা পরীক্ষা করে দেখুন:

    if os.path.isfile(fsrc):
  • প্রথম চরটি আলফা হয় বা না হয় যদি হয় তার জন্য লক্ষ্যযুক্ত ফোল্ডারটি সংজ্ঞায়িত করে:

    target = path(dr, s.upper()) if s.isalpha() else path(dr, "#")
  • ফোল্ডারটি ইতিমধ্যে উপস্থিত রয়েছে কিনা তা যাচাই করে, এটি না থাকলে তৈরি করে:

    if not os.path.exists(target):
        os.mkdir(target)
  • আইটেমটিকে তার সম্পর্কিত ফোল্ডারে স্থানান্তরিত করে:

    shutil.move(fsrc, path(target, f))

আরে জ্যাকব বড় হাতের অক্ষরের জন্য কি চেক আছে?
পার্টো

@ পার্টো একেবারে! আপনার কোন উপায়ে এটি দরকার? (আমি 3,5 ঘন্টা শিক্ষণ পরীক্ষা করতে পারি :)
জ্যাকব ভিলিজম

এটা আসলে ছিল। নিখুঁত বাস্তবায়ন।
পার্তো

বিবেচনা করার পরে, আমি বিভিন্ন কারণে এই উত্তরটি নিয়ে যাওয়ার সিদ্ধান্ত নিয়েছি: 1)। কী চলছে তার ব্যাখ্যা। 2)। উত্তরটি প্রথম চেষ্টা করে সঠিকভাবে চালানো হয়
পার্টো

11

কোড-গল্ফড কেবল দুটি কমান্ড এবং দুটি নিয়মিত অভিব্যক্তি সহ এখনও পঠনযোগ্য:

mkdir -p '#' {a..z}
prename -n 's|^[[:alpha:]]|\l$&/$&|; s|^[0-9]|#/$&|' [[:alnum:]]?*

আপনার কাছে যদি সরানোর জন্য প্রচুর পরিমাণে ফাইল থাকে তবে প্রক্রিয়া যুক্তি তালিকার সাথে ফিট করার জন্য অনেকগুলি (হ্যাঁ, এর একটি সীমা রয়েছে এবং এটি কেবল কয়েক কিলোবাইট হতে পারে), আপনি একটি আলাদা কমান্ড এবং পাইপ দিয়ে ফাইল তালিকা তৈরি করতে পারেন prenameযেমন:

find -mindepth 1 -maxdepth 1 -name '[[:alnum:]]?*' -printf '%f\n' |
prename -n 's|^[[:alpha:]]|\l$&/$&|; s|^[0-9]|#/$&|'

[[:alnum:]]?*যদি কোনও ফাইল গ্লোব প্যাটার্নের সাথে মেলে না তবে আক্ষরিক ফাইলের নামটি না সরানোর চেষ্টা করার অতিরিক্ত সুবিধা রয়েছে । findশেল গ্লোব্বিংয়ের চেয়ে আরও অনেক ম্যাচের মানদণ্ডকেও মঞ্জুরি দেয়। একটি বিকল্প হ'ল nullglobশেল বিকল্প সেট করা এবং এর স্ট্যান্ডার্ড ইনপুট স্ট্রিমটি বন্ধ করা prename1

উভয় ক্ষেত্রেই -nফাইলগুলি সরানোর জন্য স্যুইচটি সরিয়ে ফেলুন এবং কেবল সেগুলি কীভাবে সরানো হবে তা দেখান না।

সংযোজন: আপনি খালি ডিরেক্টরিগুলি আবার এটি দিয়ে সরাতে পারেন:

rmdir --ignore-fail-on-non-empty '#' {a..z}

1 shopt -s nullglob; prename ... <&-


8

আপনি যদি zsh, কিছু ফাংশন এবং কয়েকটি zmvআদেশের বিষয়ে আপত্তি রাখেন না :

mmv() {echo mkdir -p "${2%/*}/"; echo mv -- "$1" "$2";}
autoload -U zmv
zmv -P mmv '([a-zA-Z])(*.ttf)' '${(UC)1}/$1$2'
zmv -P mmv '([!a-zA-Z])(*.ttf)' '#/$1$2'

mmvফাংশন ডিরেক্টরি করে তোলে এবং ফাইল চলে আসে। zmvতারপরে প্যাটার্ন-ম্যাচিং এবং প্রতিস্থাপন সরবরাহ করে। প্রথমে, বর্ণমালা দিয়ে শুরু হওয়া ফাইলের নামগুলি সরানো, তারপরে সমস্ত কিছুই:

$ zmv -P mmv '([a-zA-Z])(*.ttf)' '${(UC)1}/$1$2'
mkdir -p A/
mv -- abcd.ttf A/abcd.ttf
mkdir -p A/
mv -- ABCD.ttf A/ABCD.ttf
$ zmv -P mmv '([!a-zA-Z])(*.ttf)' '#/$1$2'
mkdir -p #/
mv -- 123.ttf #/123.ttf
mkdir -p #/
mv -- 七.ttf #/七.ttf

ছাড়া আবার চালান echoমধ্যে mmvএর সংজ্ঞা আসলে পদক্ষেপ সম্পাদনের জন্য।


8

ডিরেক্টরিটির নামগুলি বড় হাতের (বা বড় হাতের অক্ষরের সাহায্যে ফাইলগুলি সরাতে) তৈরি করার জন্য আমি কোনও দুর্দান্ত উপায় বের করি নি, যদিও আপনি পরবর্তীকালে এটি করতে পারতেন rename...

mkdir {a..z} \#; for i in {a..z}; do for f in "$i"*; do if [[ -f "$f" ]]; then echo mv -v -- "$f" "$i"; fi; done; done; for g in [![:alpha:]]*; do if [[ -f "$g" ]]; then echo mv -v -- "$g" \#; fi; done

বা আরও সহজে পাঠযোগ্য:

mkdir {a..z} \#; 
for i in {a..z}; do 
  for f in "$i"*; do
    if [[ -f "$f" ]]; then 
      echo mv -v -- "$f" "$i"; 
    fi 
  done
done
for g in [![:alpha:]]*; do 
  if [[ -f "$g" ]]; then 
    echo mv -v -- "$g" \#
  fi
done

echoপ্রকৃতপক্ষে ফাইলগুলি সরানোর জন্য পরীক্ষার পরে সরান

এবং তারপর

rename -n 'y/[a-z]/[A-Z]/' *

-nএটি পরীক্ষার পরে ভাল লাগলে অপসারণ করুন এবং আবার চালান।


2
আপনি if [[ -d "${i^}" ]]চলক iমূলধন তৈরি করতে এবং mkdir {A..Z}শুরুতে ব্যবহার করতে পারেন ।
অ্যারোনিকাল

আমাকে এটি চেষ্টা করে দেখতে দিন
পার্টো

@ আরোনিকাল ধন্যবাদ! তবে আমি এটি ছেড়ে দেব, যেহেতু আপনি এটি নিজের মতো পোস্ট করেছেন
জান্না

@ জান্না আমি পছন্দ করি যে আমরা বিভিন্ন দিক থেকে এটি নিয়ে এসেছি, চিঠিগুলি দিয়ে পুনরাবৃত্তি করেছি এবং সেগুলি অনুসন্ধানের মানদণ্ড হিসাবে ব্যবহার করে আমার কাছে কখনও আসেনি। আমি নিশ্চিত যে সন্ধানের সাথে একটি চতুর এবং দ্রুত সমাধান আছে, তবে এটি আমার মাথা পেতে পারে না!
অ্যারোনিকাল

আরে জান্না, এটি বড় হাতের অক্ষর দিয়ে শুরু হওয়া ফন্টগুলি সরিয়ে দেয় না। অন্যথায় কাজ ভাল।
পার্টো

7

ফন্টগুলি অন্তর্ভুক্ত থাকা ডিরেক্টরিগুলির মধ্যে নিম্নলিখিত কমান্ডগুলির কাজ করা উচিত, আপনি যদি ফন্ট স্টোরেজ ডিরেক্টরিটির বাইরে থেকে ব্যবহার করতে চান তবে পরিবর্তন for f in ./*করুন for f in /directory/containing/fonts/*। এটি একটি খুব শেল ভিত্তিক পদ্ধতি, তাই বেশ ধীর এবং এটি পুনরাবৃত্তিযোগ্যও। এটি কেবলমাত্র ডিরেক্টরি তৈরি করবে, যদি এমন ফাইল থাকে যা মেলা চরিত্রের সাথে শুরু হয়।

target=/directory/to/store/alphabet/dirs
mkdir "$target"
for f in ./* ; do 
  if [[ -f "$f" ]]; then 
    i=${f##*/}
    i=${i:0:1}
    dir=${i^}
    if [[ $dir != [A-Z] ]]; then 
      mkdir -p "${target}/#" && mv "$f" "${target}/#"
    else
      mkdir -p "${target}/$dir" && mv "$f" "${target}/$dir"
    fi
  fi
done

ওয়ান লাইনার হিসাবে, ফন্ট স্টোরেজ ডিরেক্টরি থেকে আবার:

target=/directory/to/store/alphabet/dirs; mkdir "$target" && for f in ./* ; do if [[ -f "$f" ]]; then i=${f##*/}; i=${i:0:1} ; dir=${i^} ; if [[ $dir != [A-Z] ]]; then mkdir -p "${target}/#" && mv "$f" "${target}/#"; else mkdir -p "${target}/$dir" && mv "$f" "${target}/$dir" ; fi ; fi ; done

অনুরূপ স্ট্রিং ম্যানিপুলেশন সহ ফাইন্ড ব্যবহার করে একটি পদ্ধতি, বাশ প্যারামিটার সম্প্রসারণ ব্যবহার করে যা পুনরাবৃত্ত হবে এবং খাঁটি শেল সংস্করণের চেয়ে কিছুটা দ্রুত হওয়া উচিত:

find . -type f -exec bash -c 'target=/directory/to/store/alphabet/dirs ; mkdir -p "$target"; f="{}" ; i="${f##*/}"; i="${i:0:1}"; i=${i^}; if [[ $i = [[:alpha:]] ]]; then mkdir -p "${target}/$i" && mv "$f" "${target}/$i"; else mkdir -p "${target}/#" && mv "$f" "${target}/#"; fi' \;

বা আরও পঠনযোগ্য:

find . -type f -exec bash -c 'target=/directory/to/store/alphabet/dirs 
   mkdir -p "$target"
   f="{}"
   i="${f##*/}"
   i="${i:0:1}"
   i=${i^}
   if [[ $i = [[:alpha:]] ]]; then 
      mkdir -p "${target}/$i" && mv "$f" "${target}/$i"
   else
      mkdir -p "${target}/#" && mv "$f" "${target}/#"
   fi' \;

এই এক খুব কাজ। এমনকি বড় হাতের অক্ষর এবং ছোট হাতের অক্ষরের জন্য।
পারতো

5

trতারপরে mkdirএবং mv: ব্যবহার করে ডিরেক্টরি নামের প্রতিটি ফাইলের নাম ম্যাপ করুন

find /src/dir -type f -print0 |
xargs -0 -I{} bash -c \
  'dir=/dest/$(basename "{}" | cut -c1 | tr -C "a-zA-Z\n" "#" | tr "a-z "A-Z"); mkdir -p $dir; mv "{}" $dir'

আমি সত্যিই এটি পছন্দ করি, এটি অনুসন্ধানের ব্যবহারের জন্য আমার ইচ্ছার সাথে আমি আঁকড়ে ধরছিলাম the কেবলমাত্র আপার কেস ডিরেক্টরি নাম তৈরি করার এবং সেগুলির মধ্যে লোয়ার কেস ফাইলের নামগুলি সরানোর কোনও উপায় আছে?
অ্যারোনিকাল

1
আমি trবড় হাতের মধ্যে রূপান্তর করতে আরেকটি যুক্ত করেছি ।
এক্সএন

কেন মাধ্যমে বাঁক xargsমাত্র ডাকতে bashআবার? findকিছুটা লুপের আউটপুটটি পাইপ করা কি সরল এবং আরও বেশি পঠনযোগ্য readহবে না এবং এটি সেখানে রেকর্ড-বাই-রেকর্ড করে?
ডেভিড ফোস্টার 20

ভাল প্রশ্ন, @ ডেভিডফোস্টার আমি মনে করি ওয়ান-লাইনারে লুপগুলির বিরুদ্ধে পক্ষপাত এবং আরও কার্যকরী পদ্ধতির পক্ষে অগ্রাধিকার। তবে স্ট্রিংয়ের কোনও ব্যাশ স্ক্রিপ্ট খুব মার্জিত নয়, তাই আমি বলব whileলুপ সংস্করণ ( বিট.ly / 2j2mhyb ) সম্ভবত আরও ভাল।
এক্সএন

উপায় দ্বারা, আপনি কদর্য এড়াতে পারেন {}প্রতিকল্পন আপনি দিন xargsযুক্তি পরিশেষে যোগ এবং তারপর পড়ুন $1শেল স্ক্রিপ্ট ভিতরে, উদাহরণ: xargs -0 -n1 -- bash -c 'dir=/dest/$(basename "$1" | ...); ...; mv "$1" "$dir"' _। (চূড়ান্ত মনে _!)
ডেভিড ফোস্টার 20
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.