বিরল ফাইলগুলি সন্ধান করছেন?


19

আমার সিস্টেমে বা কোনও নির্দিষ্ট ডিরেক্টরি ট্রিতে সমস্ত স্পার ফাইল খুঁজে পাওয়ার কোনও সরল উপায় আছে?

যদি এটি প্রাসঙ্গিক হয় তবে আমি zshউবুন্টু 12.04 ব্যবহার করছি , যদিও বাশ / শের জন্য আরও জেনেরিক ইউনিক্স-ওয়াই উত্তর, উদাহরণস্বরূপ, ভাল হবে।

সম্পাদনা করুন : স্পষ্ট করার জন্য, আমি বিচ্ছিন্ন ফাইলগুলি অনুসন্ধান করতে চাইছি, কোনও একের বিচ্ছিন্নতা স্থিতি পরীক্ষা করে দেখছি না।



2
বিরল ফাইলগুলি অনুসন্ধান করা আপনার স্বতন্ত্র ব্যক্তির তুলনামূলক স্থিতি পরীক্ষা করতে জড়িত না বলে কী অনুভব করে?
jlliagre

উত্তর:


11

সিস্টেমে (এবং ফাইল সিস্টেমগুলি) SEEK_HOLE lseekপতাকা সমর্থন করে (আপনার উবুন্টু 12.04 যেমন এক্সট 4 তে) এবং SEEK_HOLEলিনাক্সে যেমন রয়েছে তার মান 4 হিসাবে ধরে নেওয়া :

if perl -le 'seek STDIN,0,4;$p=tell STDIN;
   seek STDIN,0,2; exit 1 if $p == tell STDIN'< the-file; then
  echo the-file is sparse
else
  echo the-file is not sparse
fi

সেই শেল সিনট্যাক্সটি পসিক্স। এটা অ পোর্টেবল উপাদান আছে perlএবং যে SEEK_HOLE

lseek(SEEK_HOLE)ফাইলের প্রথম গর্তের শুরুতে , বা কোনও ছিদ্র না পাওয়া গেলে ফাইলের শেষের দিকে খোঁজ করে । উপরে আমরা জানি ফাইলগুলি বিচ্ছিন্ন হয় না যখন ফাইলগুলি lseek(SEEK_HOLE)আমাদের শেষের দিকে নিয়ে যায় (একই জায়গায় lseek(SEEK_END))।

আপনি যদি স্পার্স ফাইলগুলি তালিকাবদ্ধ করতে চান:

find . -type f ! -size 0 -exec perl -le 'for(@ARGV){open(A,"<",$_)or
  next;seek A,0,4;$p=tell A;seek A,0,2;print if$p!=tell A;close A}' {} +

জিএনইউ find(সংস্করণ ৪.৩.৩) থেকে একটি ফাইলের স্বল্পতা সম্পর্কে -printf %Sরিপোর্ট করতে হবে। এটি ফ্রয়েস্টচুটজের জবাবের মতো একই পদ্ধতি নেয় যেহেতু এটি ফাইলের আকারের তুলনায় ডিস্কের ব্যবহারের অনুপাত গ্রহণ করে, তাই সমস্ত স্পার্স ফাইলের প্রতিবেদন করার নিশ্চয়তা দেওয়া হয় না (যেমন যখন ফাইল সিস্টেমের স্তরে সংক্ষেপণ থাকে বা যেখানে গর্ত দ্বারা স্থান সংরক্ষণ হয় না) ফাইল সিস্টেমের অবকাঠামো ওভারহেড বা বৃহত বর্ধিত বৈশিষ্ট্যগুলির জন্য ক্ষতিপূরণ), তবে এমন সিস্টেমগুলিতে কাজ করবে যা নেই বা ফাইল সিস্টেম যেখানে প্রয়োগ করা হয়নি। জিএনইউ সরঞ্জাম সহ এখানে:SEEK_HOLESEEK_HOLE

find . -type f ! -size 0 -printf '%S:%p\0' |
  awk -v RS='\0' -F : '$1 < 1 {sub(/^[^:]*:/, ""); print}'

(মনে রাখবেন যে এই উত্তরটির পূর্ববর্তী সংস্করণটি findউদাহরণস্বরূপ 3.2e-05 হিসাবে স্বল্পতা প্রকাশ করার সময় সঠিকভাবে কাজ করে নি it @ ফ্ল্যাশডেভের উত্তরটি আমার নজরে আনার জন্য ধন্যবাদ )


উপরের মত একই মন্তব্য; আমি সমস্ত বিচ্ছিন্ন ফাইলগুলি সন্ধান করার জন্য একটি উপায় খুঁজছি, কোনও নির্দিষ্ট ফাইল চেক করছি না।
অ্যান্ড্রু ফেরিয়ার

1
হয়তো find0-বাইট-ফাইলগুলিও খালি বাদ দেওয়া উচিত?
frostschutz

@ ফ্রসচুটজ, ভাল পয়েন্ট, উত্তর আপডেট হয়েছে।
স্টাফেন চেজেলাস

ভাল লাগছে find -printf '%S'! :-)
frostschutz

1
@ ব্রায়ান, trকমান্ডটি প্রতিস্থাপন করুনxargs -r0 rm -f
স্টাফেন চেজেলাস

8

সাধারণত বরাদ্দকৃত ব্লকগুলির সংখ্যা ফাইলের আকারের চেয়ে কম হলে একটি ফাইল বিচ্ছিন্ন হয় (এখানে statউবুন্টুতে পাওয়া যায় এমনটি জিএনইউ ব্যবহার করে তবে সাবধান হন যে অন্যান্য সিস্টেমে এর সাথে বেমানান বাস্তবায়ন থাকতে পারে stat)।

if [ "$((`stat -c '%b*%B-%s' -- "$file"`))" -lt 0 ]
then
    echo "$file" is sparse
else
    echo "$file" is not sparse
fi

বৈকল্পিক find: (স্টিফেন থেকে চুরি)

find . -type f ! -size 0 -exec bash -c '
    for f do
        [ "$((`stat -c "%b*%B-%s" -- "$f"`))" -lt 0 ] && printf "%s\n" "$f";
    done' {} +

আপনি সাধারণত এটির পরিবর্তে শেল স্ক্রিপ্টে রাখতেন, তারপরে শেল স্ক্রিপ্টটি কার্যকর করুন।

find . -type f ! -size 0 -exec ./sparsetest.sh {} +

উদাহরণস্বরূপ চিরাচরিত ফাইল সিস্টেমে অপ্রত্যক্ষ ব্লকগুলির ওভারহেডের জন্য কভার ব্লকগুলি পর্যাপ্ত পরিমাণে কভার করার জন্য এটি কাজ করতে পারে না, যদি বিরলতার পরিবর্তে সংকোচন বরাদ্দ স্থানের পরিমাণ হ্রাস করে।
স্টাফেন চেজেলাস

নিশ্চিত; SEEK_HOLEএটি যেমন সমস্যাযুক্ত তেমনি এটি অনেক প্ল্যাটফর্ম / ফাইল সিস্টেম সমর্থন করে না। লিনাক্সে আপনি FIEMAP/ ব্যবহার করতে পারেন FIBMAPতবে FIBMAPবিশেষত মারাত্মক ধীর গতি ... খুব ভাল উপায় বলে মনে হয় না।
frostschutz

এছাড়াও এই পদ্ধতিগুলির অনেকগুলি প্রথমে ফাইলটি সিঙ্ক করার প্রয়োজন।
frostschutz

ধন্যবাদ। যদিও এটি আসলে প্রশ্নের উত্তর দেয় না। আমি কোনও নির্দিষ্ট ফাইলের তুলনামূলক কম কিনা তা পরীক্ষা করে দেখছি না, তবে সিস্টেমে সমস্ত স্পার ফাইল খুঁজে পেতে চাই।
অ্যান্ড্রু ফেরিয়ার

1
@ অ্যান্ড্রুফেরিয়ার দুঃখিত, আমার ধারণা, আমি এটিকে একটি for file in *বা এর মধ্যে আবৃত করার পক্ষে যথেষ্ট ক্ষুদ্র find। আপনি যদি একটি একক ফাইল পরীক্ষা করতে পারেন তবে আপনি সমস্ত ফাইল পরীক্ষা করতে পারবেন ... যদিও আপনাকে এই পদ্ধতিতে ডিরেক্টরি বাদ দিতে হবে না।
frostschutz

3

উপরের স্টিফেন চ্যাজেলাস উত্তরটি% এস প্যারামিটারের সাথে থাকা কিছু স্পার্স ফাইলগুলি যেমন ভাসমান পয়েন্ট সংখ্যা হিসাবে অনুপাতের রিপোর্ট করে তা বিবেচনা করে না

9.31323e-09:./somedir/sparsefile.bin

এগুলি ছাড়াও পাওয়া যাবে

find . -type f ! -size 0 -printf '%S:%p\0' |
   sed -zn '/^\(0[^:]*:\)\|\([0-9.]\+e-.*:\)/p' |
   tr '\0' '\n'

1

একটি ফাইলের গর্তের অবস্থানগুলি কী কী তা অনুসন্ধান করার সময় আমি একটি ছোট স্ক্রিপ্ট লিখেছিলাম:

#!/usr/bin/python3
import os
import sys
import errno

def report(fname):
    fd = os.open(fname, os.O_RDONLY)
    len = os.lseek(fd, 0, os.SEEK_END)
    offset = 0
    while offset < len:
        start = os.lseek(fd, offset, os.SEEK_HOLE)
        if start == len:
            break
        try:
            offset = os.lseek(fd, start, os.SEEK_DATA)
        except OSError as e:
            if e.errno == errno.ENXIO:
                offset = len
            else:
                raise
        print(f'found hole between 0x{start:08X} and 0x{offset:08X} ({offset - start} bytes)')

if __name__ == '__main__':
    for name in sys.argv[1:]:
        report(name)

এই জিনিসগুলি যেমন মুদ্রণ করে:

$ echo -n 'a' >zeros; truncate -s $((4096*4)) zeros; test/report-holes.py zeros
found hole between 0x00001000 and 0x00004000 (12288 bytes)

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