ফ্ল্যাটেন ডিরেক্টরি কিন্তু নতুন ফাইল নাম ডিরেক্টরি ডিরেক্টরি সংরক্ষণ করুন


11

আমি কীভাবে নীচের বিন্যাসে একটি ডিরেক্টরি সমতল করতে পারি?

আগে: ./aaa/bbb/ccc.png

পরে: ./aaa-bbb-ccc.png


PS: দয়া করে বিজোড় অক্ষর (যেমন স্পেস) সহ ফাইলের নামের জন্যও অ্যাকাউন্ট করুন
নাথান জেবি

3
এছাড়াও আপনি নির্দিষ্ট করতে হবে আপনি কিভাবে সম্ভব ক্ষেত্রে যেখানে হ্যান্ডেল করতে চাইবেন ./foo/bar/baz.pngএবং ./foo-bar-baz.pngউভয় বিদ্যমান। আমি ধরে নিচ্ছি আপনি কি আগেরটির সাথে প্রতিস্থাপন করতে চান না?
jw013

আমার এক ক্ষেত্রে এটি অপ্রাসঙ্গিক, তবে উত্তরটির সত্যই এর জন্য অ্যাকাউন্ট হওয়া উচিত যাতে অন্যরা এটির উপর নির্ভর করতে পারে! ধন্যবাদ!
নাথান জেবি

উত্তর:


7

সতর্কতা: আমি এই কমান্ডগুলির বেশিরভাগ সরাসরি আমার ব্রাউজারে টাইপ করেছি। ক্যাভেট লেক্টর।

Zsh এবং zmv সহ :

zmv -o -i -Qn '(**/)(*)(D)' '${1//\//-}$2'

ব্যাখ্যা: প্যাটার্নটি **/*বর্তমান ডিরেক্টরিটির সাব-ডিরেক্টরিতে সমস্ত ফাইলের সাথে পুনরাবৃত্তভাবে মিলছে (এটি বর্তমান ডিরেক্টরিতে ফাইলগুলির সাথে মেলে না, তবে এগুলির নতুন নামকরণের প্রয়োজন নেই)। প্রথম দুটি জোড়া বন্ধনী হ'ল এমন গোষ্ঠী যা প্রতিস্থাপনের পাঠ্য হিসাবে $1এবং হিসাবে উল্লেখ করা যেতে পারে $2। চূড়ান্ত যুগল বন্ধনীগুলি গ্লোব D কোয়ালিফায়ার যুক্ত করে যাতে ডট ফাইলগুলি বাদ না যায়। -o -iএর অর্থ -iবিকল্পটি পাস করার অর্থ mvএকটি বিদ্যমান ফাইলটি ওভাররাইট করা হলে আপনাকে অনুরোধ জানানো হবে।


কেবল পসিক্স সরঞ্জাম সহ:

find . -depth -exec sh -c '
    for source; do
      case $source in ./*/*)
        target="$(printf %sz "${source#./}" | tr / -)";
        mv -i -- "$source" "${target%z}";;
      esac
    done
' _ {} +

ব্যাখ্যা: caseবিবৃতিটি বর্তমান ডিরেক্টরিটির বর্তমান ডিরেক্টরি এবং শীর্ষ-স্তরের উপ-ডিরেক্টরিগুলি বাদ দেয়। targetসোর্স ফাইল নাম (ধারণ করে $0) শীর্ষে রয়েছে ./ছিনতাই এবং সব স্ল্যাশ ড্যাশ দ্বারা প্রতিস্থাপিত, প্লাস একটি চূড়ান্ত zzফাইলের নামটি যদি নতুন লাইনের সাথে শেষ হয় তবে চূড়ান্তটি রয়েছে: অন্যথায় কমান্ড প্রতিস্থাপন এটি কেটে ফেলবে।

যদি আপনার findসমর্থন না করে -exec … +(ওপেনবিএসডি, আমি আপনাকে দেখছি):

find . -depth -exec sh -c '
    case $0 in ./*/*)
      target="$(printf %sz "${0#./}" | tr / -)";
      mv -i -- "$0" "${target%z}";;
    esac
' {} \;

বাশ (বা ksh93) এর সাহায্যে ড্রেস দ্বারা স্ল্যাশগুলি প্রতিস্থাপনের জন্য আপনাকে বাহ্যিক কমান্ডের কল করতে হবে না, আপনি স্ট্রিং প্রতিস্থাপন কনস্ট্রাক্ট দিয়ে ksh93 পরামিতি প্রসারণ ব্যবহার করতে পারেন ${VAR//STRING/REPLACEMENT}:

find . -depth -exec bash -c '
    for source; do
      case $source in ./*/*)
        source=${source#./}
        target="${source//\//-}";
        mv -i -- "$source" "$target";;
      esac
    done
' _ {} +

for sourceউদাহরণ প্রথম উপস্থাপন ফাইল / Dir মিস্ ... পরিশেষে আমি খুঁজে পাওয়া যায় নি থাকেন কেন তুমি (সাধারণত) ব্যবহার করে _যেমন $0মহান উত্তরের জন্য ধন্যবাদ :) ... এবং। তাদের কাছ থেকে আমি অনেক কিছু শিখি।
পিটার.ও

মনে রাখবেন zmv উদাহরণটি কেবল একটি শুকনো রান চালায়: এটি মুভ কমান্ডগুলি মুদ্রণ করে তবে এটি কার্যকর করে না। প্রকৃতপক্ষে এই কমান্ডগুলি কার্যকর করতে, এন-কিউনে মুছে ফেলুন।
পিটার

5

ইতিমধ্যে এখানে ভাল উত্তর থাকলেও আমি এর মধ্যে আরও স্বজ্ঞাত এটি পেয়েছি bash:

find aaa -type f -exec sh -c 'new=$(echo "{}" | tr "/" "-" | tr " " "_"); mv "{}" "$new"' \;

aaaআপনার বিদ্যমান ডিরেক্টরিটি কোথায় ? এতে থাকা ফাইলগুলি বর্তমান ডিরেক্টরিতে সরানো হবে (এএএ-তে খালি ডিরেক্টরি রেখে)। trডিরেক্টরি এবং স্পেস উভয়ই হ্যান্ডেল করার জন্য দুটি কল (পালানো স্ল্যাশগুলির জন্য যুক্তি ছাড়াই - পাঠকের জন্য অনুশীলন)।

আমি এটিকে আরও স্বজ্ঞাত এবং তুলনামূলকভাবে তুলনামূলক সহজ বলে বিবেচনা করি। অর্থাৎ আমি findকেবলমাত্র .png ফাইলগুলি সন্ধান করতে চাইলে আমি প্যারামিটারগুলি পরিবর্তন করতে পারি। আমি trকলগুলি পরিবর্তন করতে বা প্রয়োজন অনুযায়ী আরও যুক্ত করতে পারি । এবং আমি যদি echoআগে দৃষ্টিপাত করে mvপরীক্ষা করে দেখতে চাই যে এটি সঠিক কাজ করবে তবে তার আগে আমি যুক্ত করতে পারি (তবে echoজিনিসগুলি সঠিক দেখায় কেবল অতিরিক্ত ছাড়া পুনরাবৃত্তি করুন :

find aaa -name \*.png -exec sh -c 'new=$(echo "{}" | tr "/" "-" | tr " " "_"); echo mv "{}" "$new"' \;

নোট এছাড়াও আমি ব্যবহার করছি find aaa... এবং না find .... বা find aaa/... দ্বিতীয়টি চূড়ান্ত ফাইলের নামে মজার শৈল্পিক রেখে দেয়।


এই একটি লাইনারের জন্য ধন্যবাদ - এটি আমার জন্য ভাল কাজ করেছিল যখন আমি ডিরেক্টরিটির বাইরের দিক থেকে এটি করি (যা আপনি যা করতে বলেছেন ঠিক তেমন)। আমি যখন ডিরেক্টরিটির ভিতরে থেকে চেষ্টা করেছি (মূল ডিরেক্টরিটির নাম যুক্ত হওয়া এড়ানোর আশায়) সমস্ত ফাইল "অদৃশ্য হয়ে গেছে"। আমি তাদের একই ডিরেক্টরিতে লুকানো ফাইলগুলিতে পরিণত করেছিলাম।
ডিজিগ

2
find . -mindepth 2 -type f -name '*' |
  perl -l000ne 'print $_;  s/\//-/g; s/^\.-/.\// and print' |
    xargs -0n2 mv 

দ্রষ্টব্য: এটি ফাইলের নামের জন্য কাজ করবে না যা এতে রয়েছে \n
এটি অবশ্যই কেবল fফাইল টাইপ করে ...
কেবলমাত্র নাম সংঘর্ষগুলি পিডাব্লুডিতে প্রাক-বিদ্যমান ফাইলগুলি থেকে

এই বেসিক সাবসেটের সাথে পরীক্ষিত

rm -fr junk
rm -f  junk*hello*

mkdir -p  junk/junkier/junkiest
touch    'hello    hello'
touch    'junk/hello    hello'
touch    'junk/junkier/hello    hello'
touch    'junk/junkier/junkiest/hello    hello'

ফলাফল

./hello    hello
./junk-hello    hello
./junk-junkier-hello    hello
./junk-junkier-junkiest-hello    hello

0

এখানে একটি lsসংস্করণ .. মন্তব্য স্বাগত। এটি এর মতো ক্ষতিকারক ফাইল নামগুলির জন্য কাজ করে "j1ळ\n\001\n/j2/j3/j4/\nh  h\n"তবে আমি কোনও ক্ষতি সম্পর্কে জানতে আগ্রহী। "ম্যালিন্ড করা lsকি আসলে এটি করতে পারে (দৃust়ভাবে)?"

ls -AbQR1p * |                        # paths in "quoted" \escaped format
    sed -n '/":$/,${/.[^/]$/p}' |     # skip files in pwd, blank and dir/ lines
    { bwd="$PWD"; while read -n1;     # save base dir strip leading "quote
                        read -r p; do # read path
        printf -vs "${p%\"*}"         # strip trailing quote"(:)
        [[ $p == *: ]] && {           # this is a directory
            cd   "$bwd/$s"            # change into new directory
            rnp="${s//\//-}"-         # relative name prefix
        } || mv "$s" "$bwd/$rnp$s"
      done; }

-1

কেবলমাত্র ফাইলের নামটি + trকমান্ডের পথে পাইপ করুন ।tr <replace> <with>

for FILE in `find aaa -name "*.png"`
do
  NEWFILE=`echo $FILE | tr '/' '-'`
  cp -v $FILE $NEWFILE
done

1
এটি নিরাপদে বিজোড় ফাইল নামগুলি হ্যান্ডেল করে না। স্পেসগুলি এটি ভেঙে দেবে (অন্যান্য জিনিসগুলির মধ্যে)।
jw013

প্রথম নজরে, এটি একটি পরিষ্কার, পঠনযোগ্য সমাধান তবে @ jw013 ঠিক আছে, এটি স্পেসগুলি ভালভাবে পরিচালনা করবে না। সাহায্য cpকরার cp -v "$FILE" "$NEWFILE"জন্য লাইনটি পরিবর্তন করবেন ? (এছাড়াও, আপনি কেবল পিএনজি ফাইলগুলি অনুমান করা উচিত নয়))
নাথান জেবি

2
@ নাথানজে.ব্রাউয়ের cpলাইনে উদ্ধৃতি যুক্ত করা অপর্যাপ্ত। findএকটি forলুপ দিয়ে আউটপুট পার্সিংয়ের সম্পূর্ণ পদ্ধতির ত্রুটিযুক্ত। ব্যবহারের একমাত্র নিরাপদ উপায়ে findসঙ্গে আছে -exec, অথবা -print0যদি উপলব্ধ (কম পোর্টেবল -exec)। আমি আরও শক্তিশালী বিকল্পের পরামর্শ দেব তবে এই মুহূর্তে আপনার প্রশ্নটি নীচে নির্দিষ্ট করা আছে।
jw013

-2

ফাইলের নামগুলিতে স্পেসের জন্য নিরাপদ:

#!/bin/bash

/bin/find $PWD -type f | while read FILE
do
    _new="${FILE//\//-}"
    _new="${_new:1}"
    #echo $FILE
    #echo $_new

    /bin/mv "$FILE" "$_new"
done

সুস্পষ্ট কারণে cpপরিবর্তে আমার সাথে রান mv, কিন্তু একই উত্পাদন করা উচিত।


3
type find-> find is /usr/bin/findআমার মেশিনে। PATHস্ক্রিপ্টে পরিবর্তনশীল নাম হিসাবে ব্যবহার করা একটি ভয়ানক ধারণা। এছাড়াও, আপনার স্ক্রিপ্ট ম্যাঙ্গেলগুলি ফাঁকা বা ব্যাকস্ল্যাশ সহ নামগুলি ফাইল করে, কারণ আপনি readআদেশটি অপব্যবহার করেছেন (এই সাইটের জন্য অনুসন্ধান করুন IFS read -r)।
গিলস 'অশুভ হওয়া বন্ধ করুন'

find is hashed (/bin/find), প্রাসঙ্গিক কিভাবে? বিভিন্ন ডিস্ট্রো আলাদা?
টিম

জানতাম আমার এ থেকে দূরে থাকা উচিত ছিল, শকুনের টোপ
টিম

@ টিম আপনি আপনার প্রতিনিধিত্ব ফিরে পেতে উত্তরটি সর্বদা মুছতে পারেন (এবং আমার পাশাপাশি খ / সি এর জন্য ডাউনওয়েতে প্রতিবেদনের ব্যয় হয়)। স্ক্রিপ্টগুলিতে হার্ড-কোডিং পাথগুলি মনে করে যে আপনি PATHপরিবেশের পরিবর্তনশীল বিন্দুটি হারিয়েছেন যা প্রতিটি ইউনিক্স সিস্টেম ব্যবহার করে uses আপনি যদি লিখেন /bin/findতবে আপনার স্ক্রিপ্টটি আসলে প্রতিটি সিস্টেমে (গিলস, আমার, এবং সম্ভবত ওপি'র) টিতে নষ্ট হয়ে গেছে /bin/find(যেমন বি / সি এটিতে রয়েছে /usr/bin/find)। PATHপরিবেশের পরিবর্তনশীলের পুরো পয়েন্টটি এটি একটি নন-ইস্যু করা।
jw013

উপায় দ্বারা, $(pwd)ইতিমধ্যে একটি পরিবর্তনশীল উপলব্ধ: $PWD। তবে আপনাকে অবশ্যই এখানে একটি নিখুঁত পাথ ব্যবহার করা উচিত নয় : যদি আপনার স্ক্রিপ্টটি এখান থেকে বলা হয়, বলুন /home/tim, এটি নামকরণের চেষ্টা /home/tim/some/pathকরে /home-tim-some-path
গিলস 'অশুভ হওয়া বন্ধ করুন'
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.