সবার আগে ছোট ফাইল গুলো কপি করবেন?


15

আমার কাছে একটি বৃহত ডিরেক্টরি রয়েছে যার মধ্যে সাব-ডিরেক্টরি এবং ফাইল রয়েছে যা আমি পুনরাবৃত্তভাবে অনুলিপি করতে চাই।

cpফাইলের আকার অনুসারে এটি অনুলিপি অপারেশন সঞ্চালন করা উচিত যে কোনও উপায় আছে , যাতে ক্ষুদ্রতম ফাইলগুলি প্রথমে অনুলিপি করা যায়?


1
কোনও এক্সওয়াই সমস্যা জড়িত না তা নিশ্চিত করার জন্য , আপনি কেন এটি করতে চান তা ব্যাখ্যা করতে পারেন?
স্বর্ণলোকস

4
@ টাফকা'গোল্ডিলকস '- আমার কাছে প্রচুর ভিডিও ফাইল রয়েছে এবং আমি প্রতিটি ডিরেক্টরি মান পরীক্ষা করতে চাই। বাকি ফাইলগুলিও খুব খারাপ কিনা তা সম্পর্কে আমার কাছে ছোট ভিডিওটি একটি দ্রুত ইঙ্গিত দেয়।
nbubis

উত্তর:


10

এটি সমস্ত কাজ এক সাথে চলে যায় - সমস্ত শিশু ডিরেক্টরিতে, সমস্ত ফাইল ফাইল নাম ছাড়াই একক স্ট্রিমে। এটি আপনার কাছে থাকা প্রতিটি ফাইলকে ছোট থেকে বড়তে অনুলিপি করবে। mkdir ${DESTINATION}এটি ইতিমধ্যে বিদ্যমান না থাকলে আপনার প্রয়োজন হবে ।

find . ! -type d -print0 |
du -b0 --files0-from=/dev/stdin |
sort -zk1,1n | 
sed -zn 's/^[^0-9]*[0-9]*[^.]*//p' |
tar --hard-dereference --null -T /dev/stdin -cf - |
    tar -C"${DESTINATION}" --same-order -xvf -

আপনি কি জানেন, যদিও? এটি যা করে না তা হ'ল খালি শিশু ডিরেক্টরি। আমি এই পাইপলাইনের উপর দিয়ে কিছু পুনর্নির্দেশ করতে পারি, তবে এটি ঘটনার অপেক্ষা কেবল একটি রেসের শর্ত। সিম্পলস্ট সম্ভবত সেরা। সুতরাং কেবল এটি পরে করুন:

find . -type d -printf 'mkdir -p "'"${DESTINATION}"'/%p"\n' |
    . /dev/stdin

বা, যেহেতু গিলস ডিরেক্টরি অনুমতিগুলি সংরক্ষণের জন্য তার উত্তরে খুব ভাল বক্তব্য রেখেছিল, তাই আমারও চেষ্টা করা উচিত। আমি মনে করি এটি এটি করবে:

find . -type d -printf '[ -d "'"${DESTINATION}"'/%p" ] || 
    cp "%p" -t "'"${DESTINATION}"'"\n' |
. /dev/stdin

আমি mkdirযাই হোক না কেন যে দ্রুত বাজি করতে ইচ্ছুক ।


1
ধিক্কার! +1
স্বর্ণলোকস ocks

3
@ টাফকা'গোল্ডিলকস 'আমি এটিকে প্রশংসা হিসাবে গ্রহণ করব। অনেক ধন্যবাদ.
মাইকজার্ভ

15

এখানে একটি দ্রুত এবং নোংরা পদ্ধতি ব্যবহার করছে rsync। এই উদাহরণের জন্য আমি 10 এমবি এর নীচে যে কোনও কিছুকে "ছোট" হিসাবে বিবেচনা করছি।

প্রথমে কেবলমাত্র ছোট ফাইলগুলি স্থানান্তর করুন:

rsync -a --max-size=10m srcdir dstdir

তারপরে বাকী ফাইলগুলি স্থানান্তর করুন। পূর্বে স্থানান্তরিত ছোট ফাইলগুলিকে সংশোধন না করা হলে পুনরায় অনুলিপি করা হবে না।

rsync -a srcdir dstdir

থেকে man 1 rsync

   --max-size=SIZE
          This  tells  rsync to avoid transferring any file that is larger
          than the specified SIZE. The SIZE value can be suffixed  with  a
          string  to  indicate  a size multiplier, and may be a fractional
          value (e.g. "--max-size=1.5m").

          This option is a transfer rule, not an exclude,  so  it  doesnt
          affect  the  data  that  goes  into  the file-lists, and thus it
          doesnt affect deletions.  It just limits  the  files  that  the
          receiver requests to be transferred.

          The  suffixes  are  as  follows:  "K"  (or  "KiB") is a kibibyte
          (1024), "M" (or "MiB") is a mebibyte (1024*1024),  and  "G"  (or
          "GiB")  is  a gibibyte (1024*1024*1024).  If you want the multi
          plier to be 1000 instead of  1024,  use  "KB",  "MB",  or  "GB".
          (Note: lower-case is also accepted for all values.)  Finally, if
          the suffix ends in either "+1" or "-1", the value will be offset
          by one byte in the indicated direction.

          Examples:    --max-size=1.5mb-1    is    1499999    bytes,   and
          --max-size=2g+1 is 2147483649 bytes.

অবশ্যই, ফাইল-বাই-ফাইল স্থানান্তর করার ক্রমটি বৃহত্তম থেকে বৃহত্তর থেকে কঠোর নয়, তবে আমি মনে করি এটি আপনার সমাধানগুলির প্রয়োজনীয়তা পূরণ করে এমন সহজ সমাধান হতে পারে।


এখানে আপনি হার্ড-লিঙ্কগুলির 2 কপি পেয়েছেন এবং সফট-লিঙ্কগুলি প্রতিটির দুটি অনুলির জন্য প্রকৃত ফাইলগুলিতে রূপান্তরিত হয়েছে। আপনি --copy-dest=DIRএবং / অথবা --compare-dest=DIRআমার মনে হয় এর সাথে আপনি আরও অনেক কিছু করতে পারেন । আমি কেবল জানি কারণ আমার নিজের উত্তর পোস্ট --hard-dereferenceকরার tarপরে নিজেকে যুক্ত করতে হয়েছিল কারণ আমি লিঙ্কগুলি অনুপস্থিত ছিল। আমি মনে করি rsyncপ্রকৃতপক্ষে অন্যদের সাথে স্থানীয় ফাইল সিস্টেমগুলির সাথে আরও সুনির্দিষ্ট আচরণ করে - আমি এটি ইউএসবি কী দিয়ে ব্যবহার করতাম এবং যদি আমি ব্যান্ডউইথের সীমা নির্ধারণ না করি তবে এটি বাসে প্লাবিত হবে। আমি মনে করি পরিবর্তে অন্যদের মধ্যে আমার ব্যবহার করা উচিত ছিল।
মাইকজারভ

1
"দ্রুত এবং নোংরা পদ্ধতি" এর জন্য +1। সহজতর কমপক্ষে স্বয়ংক্রিয়তার উদ্দেশ্যে এবং ভবিষ্যতের রক্ষণাবেক্ষণের জন্য আরও ভাল better আমি মনে করি এটি আসলে বেশ পরিষ্কার। "মার্জিত" বনাম "ক্লডগি" এবং "শক্তিশালী" বনাম "অস্থির" কখনও কখনও নকশার লক্ষ্য হিসাবে দ্বন্দ্ব করতে পারে তবে একটি ভাল ভারসাম্য রয়েছে যা আঘাত হানতে পারে, এবং আমি মনে করি এটি মার্জিত এবং মোটামুটি শক্তিশালী।
ওয়াইল্ডকার্ড

4

cpসরাসরি নয় , এটি তার দক্ষতার বাইরেও। তবে আপনি cpসঠিক ক্রমে ফাইলগুলি কল করার ব্যবস্থা করতে পারেন ।

জেডএস সুবিধামতভাবে গ্লোব কোয়ালিফায়ার দিয়ে আকার অনুসারে ফাইলগুলি বাছাইয়ের অনুমতি দেয় । এখানে একটি zsh স্নিপেট যা কপি নীচ থেকে আকার ক্রম বৃদ্ধি ফাইল এর /path/to/source-directoryনীচে /path/to/destination-directory

cd /path/to/source-directory
for x in **/*(.oL); do
  mkdir -p /path/to/destination-directory/$x:h
  cp $x /path/to/destination-directory/$x:h
done

একটি লুপের পরিবর্তে, আপনি zcpফাংশনটি ব্যবহার করতে পারেন । তবে আপনাকে প্রথমে গন্তব্য ডিরেক্টরিগুলি তৈরি করতে হবে যা একটি ক্রিপ্টিক অনলাইনারে করা যেতে পারে।

autoload -U zmv; alias zcp='zmv -C'
cd /path/to/source-directory
mkdir **/*(/e\''REPLY=/path/to/destination-directory/$REPLY'\')
zcp -Q '**/*(.oL)' '/path/to/destination-directory/$f'

এটি উত্স ডিরেক্টরিগুলির মালিকানা সংরক্ষণ করে না। যদি আপনি এটি চান তবে আপনাকে উপযুক্ত কপি করার প্রোগ্রাম যেমন cpioবা হিসাবে তালিকাভুক্ত করতে হবে pax। যদি আপনি এটি করেন, আপনাকে কল করার cpবা zcpঅতিরিক্ত সংযোজন করতে হবে না ।

cd /path/to/source-directory
print -rN **/*(^.) **/*(.oL) | cpio -0 -p /path/to/destination-directory

2

আমি cp -rসরাসরি এটি করার কোন উপায় আছে বলে মনে করি না । যেহেতু আপনি উইজার্ডলি find/ awkসলিউশন পাওয়ার আগে এটি একটি অনির্দিষ্ট সময়ের হতে পারে , তাই এখানে একটি দ্রুত পার্ল স্ক্রিপ্ট রয়েছে:

#!/usr/bin/perl
use strict;
use warnings FATAL => qw(all);

use File::Find;
use File::Basename;

die "No (valid) source directory path given.\n"
    if (!$ARGV[0] || !-d -r "/$ARGV[0]");

die "No (valid) destination directory path given.\n"
    if (!$ARGV[1] || !-d -w "/$ARGV[1]");

my $len = length($ARGV[0]);
my @files;
find (
    sub {
        my $fpath = $File::Find::name;
        return if !-r -f $fpath;
        push @files, [
            substr($fpath, $len),
            (stat($fpath))[7],
        ]
    }, $ARGV[0]
);

foreach (sort { $a->[1] <=> $b->[1] } @files) {
    if ($ARGV[2]) {
        print "$_->[1] $ARGV[0]/$_->[0] -> $ARGV[1]/$_->[0]\n";
    } else {
        my $dest = "$ARGV[1]/$_->[0]";
        my $dir = dirname($dest);
        mkdir $dir if !-e $dir;
        `cp -a "$ARGV[0]/$_->[0]" $dest`;
    }
} 
  • এটা ব্যবহার কর: ./whatever.pl /src/path /dest/path

  • তর্কগুলি উভয়ই পরম পাথ হওয়া উচিত ; ~, বা শেলটি পরম পথে প্রসারিত অন্য যে কোনও কিছুই ঠিক আছে।

  • যদি আপনি কোনও তৃতীয় যুক্তি যুক্ত করেন (আক্ষরিক ব্যতীত অন্য কিছু 0), এটি অনুলিপি না করে এটি কী করবে তার একটি প্রতিবেদন প্রিন্ট করবে, ফাইল আকারে বাইটে চাপানো যেমন, উদাহরণস্বরূপ

    4523 /src/path/file.x -> /dest/path/file.x
    12124 /src/path/file.z -> /dest/path/file.z

    লক্ষ্য করুন এগুলি আকার অনুসারে আরোহণের ক্রমে রয়েছে।

  • cpতাই আপনি যাই হোক না কেন আপনি সুইচ (আমি শুধু ব্যবহৃত চান করতে পারেন লাইন 34 উপর কমান্ড, একটি আক্ষরিক শেল কমান্ড -aসব বৈশিষ্ট্যগুলো সংরক্ষণ করা)।

  • File::Findএবং File::Basenameউভয়ই মূল মডিউল, অর্থাত্ তারা পার্লের সমস্ত ইনস্টলেশনে উপলব্ধ।


যুক্তিযুক্তভাবে, এটি এখানে একমাত্র সঠিক উত্তর। নাকি এটি ছিল ... শিরোনাম - সবেমাত্র পরিবর্তন হয়েছে ...? আমার ব্রাউজার উইন্ডো বলা হয় cp - copy smallest files first?কিন্তু পোস্টের শিরোনাম ঠিক হয় copy smallest files first?যাই হোক, অপশন কখনো আঘাত আমার দর্শন, কিন্তু এখনও, আপনি এবং ডেভিড শুধুমাত্র লোক যে ব্যবহার করা হয় cpএবং আপনি শুধুমাত্র এক এটি টানা বন্ধ করছি।
মাইকজারভ

@ মিমিকার্ভর কেবলমাত্র আমি ব্যবহার করলাম cpকারণ এটি (ক্রস-প্ল্যাটফর্ম ওরিয়েন্টেড) পার্লে * নিক্স ফাইলের বৈশিষ্ট্য সংরক্ষণের সহজতম উপায়। আপনার ব্রাউজার বারটি বলার কারণটি cp - হ'ল একটি (আইএমও বোকা) এসই বৈশিষ্ট্য যার মাধ্যমে নির্বাচিত ট্যাগগুলির মধ্যে সর্বাধিক জনপ্রিয় আসল শিরোনামের উপসর্গযুক্ত প্রদর্শিত হবে।
স্বর্ণলোক 21

ঠিক আছে, তাহলে আমি আমার প্রশংসা প্রত্যাহার করছি। সত্যিই নয়, আপনি প্রায়শই pearlপ্রায় কাছাকাছি কাঠের কাজ থেকে বেরিয়ে আসতে দেখেন না ।
মাইকজারভেজ

1

অন্য বিকল্পটি ডু থেকে আউটপুট সহ সিপি ব্যবহার করা হবে:

oldIFS=$IFS
IFS=''
for i in $(du -sk *mpg | sort -n | cut -f 2)
do
    cp $i destination
done
IFS=$oldIFS

এটি এখনও এক লাইনে করা যেতে পারে তবে আমি এটি বিভক্ত করেছি যাতে আপনি এটি পড়তে পারেন


আপনার কি কমপক্ষে $ আইএফএস সম্পর্কে কিছু করার দরকার নেই?
মাইকসার্ভ

হ্যাঁ ... আমি ধরেই নিচ্ছি যে কারওরই ফাইল নামগুলিতে নতুন লাইন নেই
ডেভিড উইলকিন্স

1
এটি ওপি বর্ণিত ডিরেক্টরি শ্রেণিবিন্যাসের মাধ্যমে পুনরাবৃত্তি পরিচালনা করবে বলে মনে হয় না।
সিপিজিনিউসএমভি

1
@cpugeniusmv সঠিক ... আমি একরকম পুনরাবৃত্তির অংশটি মিস করেছি .... পুনরাবৃত্তি পরিচালনা করতে আমি এটিকে পরিবর্তন করতে পারি, তবে আমি মনে করি এই মুহূর্তে অন্যান্য উত্তরগুলি আরও ভাল কাজ করবে। যদি কেউ প্রশ্নটি দেখে এটি সহায়তা করে তবে আমি এটি এখানে রেখে দেব।
ডেভিড উইলকিনস

1
@ ডেভিডওয়িলকিন্স - এটি অনেক সাহায্য করে।
এনবিউবিস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.