linux - সফটওয - লেখালেখির গুরুত্ব




কিভাবে একটি ডিরেক্টরি খুঁজে বের করতে। হুকুম (20)

আমি সব জাভাস্ক্রিপ্ট ফাইলের জন্য একটি find কমান্ড চালানোর চেষ্টা করছি, কিন্তু কিভাবে আমি একটি নির্দিষ্ট ডিরেক্টরি বাদ দিতে পারি?

এখানে আমরা ব্যবহার করছি কোড find

for file in $(find . -name '*.js')
do 
  java -jar config/yuicompressor-2.4.2.jar --type js $file -o $file
done

-পথ-প্রোুন পদ্ধতিটি পথের মধ্যে ওয়াইল্ডকার্ডগুলির সাথেও কাজ করে। এখানে একটি অনুসন্ধান বিবৃতি যা জিটি অভ্যন্তরীণ ডিরেক্টরিগুলি ছাড়ার জন্য একাধিক গিট repositiories সরবরাহকারী একটি গিট সার্ভারের জন্য ডিরেক্টরি খুঁজে পাবে:

find . -type d \
   -not \( -path */objects -prune \) \
   -not \( -path */branches -prune \) \
   -not \( -path */refs -prune \) \
   -not \( -path */logs -prune \) \
   -not \( -path */.git -prune \) \
   -not \( -path */info -prune \) \
   -not \( -path */hooks -prune \)  

-পুন বিকল্প ব্যবহার করুন। সুতরাং, কিছু ভালো:

find . -type d -name proc -prune -o -name '*.js'

'প্রকার ডি-নাম proc -prune' শুধুমাত্র প্রসেস নামক ডিরেক্টরিগুলির জন্য বাদ দেয়।
'-O' একটি 'OR' অপারেটর।


UNIX এর পুরানো সংস্করণগুলির মধ্যে আপনার জন্য যারা -পথ বা না ব্যবহার করতে পারে না

সানসেস 5.10 ব্যাশ 3.2 এবং সানসেস 5.11 ব্যাশ 4.4 -এ পরীক্ষা করা হয়েছে

find . -type f -name "*" -o -type d -name "*excluded_directory*" -prune -type f

আগের কোন উত্তরই উবুন্টুতে ভাল। এটা চেষ্টা কর:

find . ! -path "*/test/*" -type f -name "*.js" ! -name "*-min-*" ! -name "*console*"

আমি এই here পাওয়া here


আমার যা দরকার ছিল তা এইরকম কাজ করে, রুট থেকে শুরু করে সার্ভারে landscape.jpg খুঁজে বের করে এবং /var ডিরেক্টরিতে অনুসন্ধান বাদে:

find / -maxdepth 1 -type d | grep -v /var | xargs -I '{}' find '{}' -name landscape.jpg

find / -maxdepth 1 -type d সব ডি ডিরেক্টরির ries তালিকা /

grep -v /var তালিকা থেকে `/ var 'বাদ দেয়

xargs -I '{}' find '{}' -name landscape.jpg কোনও কমান্ড কার্যকর করুন, যেমন তালিকা থেকে প্রতিটি ডিরেক্টরি / ফলাফলের সাথে find


আমি xgettext জন্য ফাইলগুলির তালিকা সরবরাহ করার জন্য xgettext ব্যবহার xgettext , এবং একটি নির্দিষ্ট ডিরেক্টরি এবং এর বিষয়বস্তুগুলিকে বাদ দিতে চেয়েছিলাম। আমি -path মিলিত -path অনেক ক্রমাঙ্কন চেষ্টা -prune তবে আমি যে ডিরেক্টরিটি চেয়েছিলাম তা সম্পূর্ণরূপে বাদ দিতে অক্ষম ছিলাম।

আমি যে ডিরেক্টরিটি উপেক্ষা করতে চেয়েছিলাম তার বিষয়বস্তু উপেক্ষা করতে সক্ষম হয়েছিলাম, তবে find নিজেই ফলাফলগুলির মধ্যে একটি হিসাবে ফিরিয়ে আনা হয়েছিল, ফলে ফলাফলের ফলে xgettext ক্র্যাশ হতে পারে (ডিরেক্টরিগুলি গ্রহণ করা হয় না; শুধুমাত্র ফাইলগুলি)।

আমার সমাধানটি যে ফলাফলটি আমি চাই না সেটি এড়িয়ে যাওয়ার জন্য grep -v ব্যবহার করতে হয়েছিল:

find /project/directory -iname '*.php' -or -iname '*.phtml' | grep -iv '/some/directory' | xargs xgettext

যে 100% কাজ করবে find জন্য একটি যুক্তি আছে বা না, আমি নির্দিষ্ট জন্য বলতে পারেন না। grep ব্যবহার করে কিছু মাথা ব্যাথা পরে দ্রুত এবং সহজ সমাধান ছিল।


আমি উপরের কমান্ড চেষ্টা করেছি, কিন্তু "প্রো-প্রুন" ব্যবহার করে কেউ আমার জন্য কাজ করে না। অবশেষে আমি নিচের কমান্ডটি দিয়ে চেষ্টা করেছিলাম:

find . \( -name "*" \) -prune -a ! -name "directory"

আমি নোট নোট পছন্দ করি ... এটি আরও পঠনযোগ্য:

find . -name '*.js' -and -not -path directory

এই আমার জন্য কাজ যে একমাত্র।

find / -name NameOfFile ! -path '*/Directory/*'

"ডিরেক্টরীঅফফাইল" অনুসন্ধানের জন্য "ডিরেক্টরি" বাদ দেওয়া হচ্ছে। বড় উপর জোর দেওয়া *।


এই বিন্যাসটি আমি কিছু পথ বাদ দেওয়ার জন্য ব্যবহার করেছি:

$ find ./ -type f -name "pattern" ! -path "excluded path" ! -path "excluded path"

আমি "। *" পাথগুলিতে থাকা সমস্ত ফাইল খুঁজে বের করার জন্য এটি ব্যবহার করেছি:

$ find ./ -type f -name "*" ! -path "./.*" ! -path "./*/.*"

একটি ডিরেক্টরি skipping জন্য পছন্দসই সিনট্যাক্স কি হিসাবে এখানে পরিষ্কারভাবে কিছু বিভ্রান্তি আছে।

জিএনইউ মতামত

To ignore a directory and the files under it, use -prune

জিএনইউ থেকে মানুষ পাতা খুঁজে

যুক্তি

-prune একটি ডিরেক্টরি মধ্যে descending থেকে find স্টপ। শুধু নির্দিষ্ট করা হবে -not -path এখনও অব্যবহৃত ডিরেক্টরিতে নেমে আসবে, কিন্তু যখনই প্রতিটি ফাইল পরীক্ষা করে না তখন -not -path হবে না।

-prune সঙ্গে সমস্যা

-prune এটা কি উদ্দেশ্যে করা হয়, কিন্তু এটি ব্যবহার করার সময় যত্ন নিতে কিছু জিনিস এখনও আছে।

  1. মুদ্রিত ডিরেক্টরি প্রিন্ট find

    • সত্য যে উদ্দেশ্যে আচরণ করা হয়, এটা শুধু এটি মধ্যে নিচে না। ডিরেক্টরিটি সম্পূর্ণভাবে মুদ্রণ এড়াতে, একটি সিনট্যাক্স ব্যবহার করুন যা যুক্তিযুক্তভাবে বাদ দেয়।
  2. -prune শুধুমাত্র -prune এবং অন্য কোন কাজ সঙ্গে কাজ করে।

    • সত্য না-prune ছাড়া ছাড়া কোনো কর্ম সঙ্গে কাজ করে। কেন এটা মুছে ফেলার সাথে কাজ করে না? কাজ করার জন্য -delete মুছে ফেলার জন্য, ডিএফএস অর্ডারের ডিরেক্টরিটি অতিক্রম করতে হবে, যেহেতু -delete প্রথমে পাতাগুলি মুছে -delete , তারপরে পাতার পিতা-মাতার ইত্যাদি মুছে -delete ... কিন্তু -prune করার জন্য -prune নির্দিষ্ট করার জন্য, একটি আঘাত করতে হবে ডিরেক্টরি এবং এটি অবতরণ বন্ধ, যা স্পষ্টভাবে কোন -delete বা -delete সঙ্গে কোন জ্ঞান করে তোলে।

কর্মক্ষমতা

আমি এই প্রশ্নের উপরে তিনটি উপরে উল্লিখিত উত্তরগুলির একটি সহজ পরীক্ষা সেট করেছি (প্রতিস্থাপিত -exec bash -c 'echo $0' {} \; সাথে -exec bash -c 'echo $0' {} \; অন্য একটি কর্ম উদাহরণ দেখানোর জন্য)। ফলাফল নিচে

----------------------------------------------
# of files/dirs in level one directories
.performance_test/prune_me     702702    
.performance_test/other        2         
----------------------------------------------

> find ".performance_test" -path ".performance_test/prune_me" -prune -o -exec bash -c 'echo "$0"' {} \;
.performance_test
.performance_test/other
.performance_test/other/foo
  [# of files] 3 [Runtime(ns)] 23513814

> find ".performance_test" -not \( -path ".performance_test/prune_me" -prune \) -exec bash -c 'echo "$0"' {} \;
.performance_test
.performance_test/other
.performance_test/other/foo
  [# of files] 3 [Runtime(ns)] 10670141

> find ".performance_test" -not -path ".performance_test/prune_me*" -exec bash -c 'echo "$0"' {} \;
.performance_test
.performance_test/other
.performance_test/other/foo
  [# of files] 3 [Runtime(ns)] 864843145

উপসংহার

F10bit এর সিনট্যাক্স এবং ড্যানিয়েল সি। সোবারালের সিনট্যাক্স উভয় গড় রান করার জন্য 10-25 মি। GetFree এর সিনট্যাক্স , যা -prune ব্যবহার করে না, 865ms নেন। সুতরাং, হ্যাঁ এটি বরং একটি চরম উদাহরণ, তবে আপনি রান সময় সম্পর্কে যত্ন -prune এবং দূরবর্তীভাবে কিছু সন্নিবেশ করছেন তা হলে আপনি -prune ব্যবহার করতে হবে।

দ্রষ্টব্য ড্যানিয়েল সি । -prune সিনট্যাক্স দুটি -prune সিনট্যাক্সের ভাল সঞ্চালিত; কিন্তু, আমি দৃঢ়ভাবে সন্দেহ করি যে এই ক্র্যাশিংয়ের ফলাফলটি হ'ল সেই ক্রমটি স্যুইচিংয়ের ফলে যার ফলে দুইটি বিপরীত ফলাফলের ফলস্বরূপ ঘটে, যখন নন-প্রিন সংস্করণ সর্বদা ধীর গতিতে ছিল।

টেস্ট স্ক্রিপ্ট

#!/bin/bash

dir='.performance_test'

setup() {
  mkdir "$dir" || exit 1
  mkdir -p "$dir/prune_me/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/w/x/y/z" \
    "$dir/other"

  find "$dir/prune_me" -depth -type d -exec mkdir '{}'/{A..Z} \;
  find "$dir/prune_me" -type d -exec touch '{}'/{1..1000} \;
  touch "$dir/other/foo"
}

cleanup() {
  rm -rf "$dir"
}

stats() {
  for file in "$dir"/*; do
    if [[ -d "$file" ]]; then
      count=$(find "$file" | wc -l)
      printf "%-30s %-10s\n" "$file" "$count"
    fi
  done
}

name1() {
  find "$dir" -path "$dir/prune_me" -prune -o -exec bash -c 'echo "$0"'  {} \;
}

name2() {
  find "$dir" -not \( -path "$dir/prune_me" -prune \) -exec bash -c 'echo "$0"' {} \;
}

name3() {
  find "$dir" -not -path "$dir/prune_me*" -exec bash -c 'echo "$0"' {} \;
}

printf "Setting up test files...\n\n"
setup
echo "----------------------------------------------"
echo "# of files/dirs in level one directories"
stats | sort -k 2 -n -r
echo "----------------------------------------------"

printf "\nRunning performance test...\n\n"

echo \> find \""$dir"\" -path \""$dir/prune_me"\" -prune -o -exec bash -c \'echo \"\$0\"\'  {} \\\;
name1
s=$(date +%s%N)
name1_num=$(name1 | wc -l)
e=$(date +%s%N)
name1_perf=$((e-s))
printf "  [# of files] $name1_num [Runtime(ns)] $name1_perf\n\n"

echo \> find \""$dir"\" -not \\\( -path \""$dir/prune_me"\" -prune \\\) -exec bash -c \'echo \"\$0\"\' {} \\\;
name2
s=$(date +%s%N)
name2_num=$(name2 | wc -l)
e=$(date +%s%N)
name2_perf=$((e-s))
printf "  [# of files] $name2_num [Runtime(ns)] $name2_perf\n\n"

echo \> find \""$dir"\" -not -path \""$dir/prune_me*"\" -exec bash -c \'echo \"\$0\"\' {} \\\;
name3
s=$(date +%s%N)
name3_num=$(name3 | wc -l)
e=$(date +%s%N)
name3_perf=$((e-s))
printf "  [# of files] $name3_num [Runtime(ns)] $name3_perf\n\n"

echo "Cleaning up test files..."
cleanup

একাধিক ডিরেক্টরি বাদ দিতে:

find . -name '*.js' -not \( -path "./dir1" -o -path "./dir2/*" \)

ডিরেক্টরি যুক্ত করতে, add -o -path "./dirname/*" :

find . -name '*.js' -not \( -path "./dir1" -o -path "./dir2/*" -o -path "./dir3/*"\)

তবে বহিষ্কৃত অনেক ডিরেক্টরি থাকলেও আপনাকে নিয়মিত অভিব্যক্তিটি ব্যবহার করতে হবে।


এটি একটি ম্যাকে আমার জন্য উপযুক্ত:

find . -name *.php -or -path "./vendor" -prune -or -path "./app/cache" -prune

এটি php সহ suffixed যা সার্চ নাম জন্য vendor এবং app/cache dir বাদ দেওয়া হবে।


এটি কাজ করে কারণ " { foo * " প্যাটার্নের জন্য পরীক্ষার ফাইলগুলি পরীক্ষা করে দেখুন:

find ! -path "dir1" ! -path "dir2" -name "*foo*"

কিন্তু আপনি যদি কোনও প্যাটার্ন ব্যবহার না করেন তবে এটি কাজ করে না ( find ফাইলটি পরীক্ষা করে না)। সুতরাং find তার প্রাক্তন মূল্যায়ন " সত্য " এবং " মিথ্যা " bools কোন ব্যবহার করে তোলে। উপরে উল্লেখ্য সঙ্গে ব্যবহার ক্ষেত্রে কাজ না করার জন্য উদাহরণ:

find ! -path "dir1" ! -path "dir2" -type f

কোন পরীক্ষার পরীক্ষা আছে! তাই যদি আপনি কোন প্যাটার্ন মিলে ব্যবহার ছাড়া ফাইল খুঁজে পেতে প্রয়োজন -prune।এছাড়াও, প্রুন ব্যবহার করে findসবসময় দ্রুততর হয় তবে এটি সত্যিই মিলে যাওয়ার পরিবর্তে সেই ডিরেক্টরিগুলিকে ছাড়িয়ে যায় বা এটি ভালভাবে মেলে না। সুতরাং যে ক্ষেত্রে কিছু ভালো ব্যবহার করুন:

find dir -not \( -path "dir1" -prune \) -not \( -path "dir2" -prune \) -type f

বা:

find dir -not \( -path "dir1" -o -path "dir2" -prune \) -type f

শুভেচ্ছা সহ


প্রুন সুইচটি ব্যবহার করুন, উদাহরণস্বরূপ আপনি যদি misc ডিরেক্টরিটি বাদ দিতে চান তবে আপনার অনুসন্ধান কমান্ডটিতে একটি -path ./misc -prune -o যোগ করুন:

find . -path ./misc -prune -o -name '*.txt' -print

এখানে একাধিক ডিরেক্টরি সঙ্গে একটি উদাহরণ:

find . -type d \( -path dir1 -o -path dir2 -o -path dir3 \) -prune -o -print

এখানে আমরা dir1, dir2 এবং dir3 বাদ দিয়েছি, যেহেতু এক্সপ্রেশন এক্সপ্রেশন এটি একটি ক্রিয়া, যা মানদন্ডের উপর কাজ করে - -path dir1 -o -path dir2 -o -path dir3 (যদি dir1 বা dir2 বা dir3), type -d ডি সহ । আরও কর্ম হয় -o print , শুধু মুদ্রণ।


যদি -prune আপনার জন্য কাজ করে না, এই হবে:

find -name "*.js" -not -path "./directory/*"

-prune স্পষ্টভাবে কাজ করে এবং সেরা উত্তর কারণ এটি আপনি যে -prune বাদ দিতে চান তাতে -prune প্রতিরোধ করে। -not -path যা এখনও বাদ দেওয়া dir অনুসন্ধান করে, এটি কেবল ফলাফলটি মুদ্রণ করে না, যা বাদ দেওয়া -not -path নেটওয়ার্ক ভলিউম মাউন্ট করা হয় বা আপনি অনুমতি না দিলে এটি একটি সমস্যা হতে পারে।

চতুর অংশটি হল যে যুক্তিটি আর্গুমেন্টগুলির ক্রম সম্পর্কে খুব নির্দিষ্ট, তাই যদি আপনি তাদের সঠিকভাবে না পান তবে আপনার কমান্ডটি কাজ করবে না। আর্গুমেন্ট আদেশ সাধারণত যেমন:

find {path} {options} {action}

{path} : প্রথম মত, সমস্ত পথ সম্পর্কিত আর্গুমেন্ট রাখুন . -path './dir1' -prune -o . -path './dir1' -prune -o

{options} : এই গ্রুপে শেষ বিকল্প হিসাবে -name, -iname, etc নির্বাণ করার সময় আমার সবচেয়ে সফলতা রয়েছে। Eg -type f -iname '*.js'

{action} : -prune ব্যবহার করার সময় আপনি যোগ- -prune করতে চান

এখানে একটি কাজের উদাহরণ:

# setup test
mkdir dir1 dir2 dir3
touch dir1/file.txt; touch dir1/file.js
touch dir2/file.txt; touch dir2/file.js
touch dir3/file.txt; touch dir3/file.js

# search for *.js, exclude dir1
find . -path './dir1' -prune -o -type f -iname '*.js' -print

# search for *.js, exclude dir1 and dir2
find . \( -path './dir1' -o -path './dir2' \) -prune -o -type f -iname '*.js' -print

how-to-use-prune-option-of-find-in-sh -prune how-to-use-prune-option-of-find-in-sh -prune কীভাবে -prune কাজ করে তা নিয়ে লরেন্স গনসালভসের একটি চমৎকার উত্তর।

এবং এখানে জেনেরিক সমাধান:

find /path/to/search                    \
  -type d                               \
    \( -path /path/to/search/exclude_me \
       -o                               \
       -name exclude_me_too_anywhere    \
     \)                                 \
    -prune                              \
  -o                                    \
  -type f -name '*\.js' -print

টাইপিং /path/to/seach/ একাধিকবার এড়াতে, একটি pushd .. popd খুঁজুন মোড়ানো pushd .. popd pair।

pushd /path/to/search;                  \
find .                                  \
  -type d                               \
    \( -path ./exclude_me               \
       -o                               \
       -name exclude_me_too_anywhere    \
     \)                                 \
    -prune                              \
  -o                                    \
  -type f -name '*\.js' -print;         \
 popd

জন্য FreeBSD ব্যবহারকারী:

 find . -name '*.js' -not -path '*exclude/this/dir*'

 find . -name '*.js' -\! -name 'glob-for-excluded-dir' -prune





find