একাধিক ডিরেক্টরি সন্ধানে -উপুন বিকল্পে পাস করা


9

আমি findব্যাকআপ ফাইলগুলি সনাক্ত করতে এবং মুছতে ব্যবহার করছি তবে অনুসন্ধান থেকে নির্দিষ্ট ডিরেক্টরিগুলি বাদ দিতে চাই। ব্যাকআপ ফাইলের নামের মধ্যে বিনষ্ট পারে .bck, bak, ~, অথবা backup

বাদ দিতে কেবল তিনটি ডিরেক্টরি সহ ন্যূনতম কার্যকারী উদাহরণ (এমডাব্লুই) কোডটি হ'ল:

#! /bin/bash
find . -type d \( -path "./.*" -o -path "./Music" -o -path "./Documents" \) -prune -o -type f \( -name "*.bck" -o -name "*.bak" -o -name "*~" -o -name "*.backup" \) -print0 | xargs -0 --no-run-if-empty trash-put

সিনট্যাক্সটি \( -path "dir1" -o -path "dir2" ... -o -path "dirN" \) -pruneকিছুটা বিশৃঙ্খল বলে মনে হচ্ছে, বিশেষত যদি বাদ দিতে প্রায় দশটি ডিরেক্টরি থাকে তবে আমি এমডব্লিউইতে কেবল তিনটি দেখিয়েছি।

কোনও ইনপুট ফাইল ব্যবহার করে বাদ দেওয়া ডিরেক্টরিগুলির তালিকা সহ বা আরে- বা তালিকার মতো কনস্ট্রাক্ট, যা পরিষেবাতে চাপ দেওয়া যেতে পারে তার চেয়ে আরও কি সুন্দর উপায় আছে?

আমি আমার আসল প্রশ্নটি লেখার সময় আরও স্পষ্ট না হওয়ার জন্য দুঃখিত।

এনবি: trash-putএকটি ইউটিলিটি যা ফাইলগুলি Trashcanমুছার পরিবর্তে [1] এ সরিয়ে দেয়।

[1]। https://github.com/andreafrancia/trash-cli

উত্তর:


4

আমি যতদূর জানি, কোনও findফাইল থেকে নিদর্শনগুলি পড়তে বলার কোনও বিকল্প নেই । একটি সহজ কার্যসংক্রান্ত নিদর্শন আমি একটি ফাইলে অগ্রাহ্য এবং একটি বিপরীত জন্য ইনপুট হিসাবে যে ফাইল প্রেরণ করতে ইচ্ছুক রক্ষা করা grep। উদাহরণ হিসাবে, আমি নিম্নলিখিত ফাইল এবং ডিরেক্টরি তৈরি করেছি:

$ tree -a
.
├── a
├── .aa
├── .aa.bak
├── a.bck
├── b
├── .dir1
│   └── bb1.bak
├── dir2
│   └── bb2.bak
├── b.bak
├── c
├── c~
├── Documents
│   └── Documents.bak
├── exclude.txt
├── foo.backup
└── Music
    └── Music.bak

যদি আমি উদাহরণস্বরূপ আপনি সঠিকভাবে পোস্ট বোঝা, আপনি স্থানান্তর করতে চান a.bck, .aa.bak, b.bak, c~, foo.backupএবং dir2/bb2.bakআবর্জনা এবং ছেড়ে .aa.bak, .dir1/bb1.bak, Documents/Documents.bakএবং Music/Music.bakতারা কোথায়। অতএব, আমি exclude.txtনিম্নলিখিত বিষয়বস্তু দিয়ে ফাইলটি তৈরি করেছি (আপনি যতগুলি চান যোগ করতে পারেন):

$ cat exclude.txt 
./.*/
./Music
./Documents

আমি ব্যবহার করি ./.*/কারণ আমি আপনার আসল অনুসন্ধানটি বোঝার অর্থ বোঝাতে চাইছি আপনি .fooবর্তমান ডিরেক্টরিতে থাকা লুকানো ব্যাকআপ ফাইলগুলি ( ) সরাতে চান তবে লুকানো ডিরেক্টরিতে ( .foo/bar) থাকা কোনও ব্যাকআপ ফাইল বাদ দিতে পারেন । সুতরাং, আমি এখন findকমান্ডটি চালাতে পারি এবং grepঅযাচিত ফাইলগুলি বাদ দিতে ব্যবহার করতে পারি:

$ find . -type f | grep -vZf exclude.txt | xargs -0 --no-run-if-empty trash-put

গ্রেপ বিকল্পগুলি:

   -v, --invert-match
          Invert  the  sense  of matching, to select non-matching
          lines.  (-v is specified by POSIX.)
   -f FILE, --file=FILE
          Obtain patterns from FILE, one  per  line.   The  empty
          file  contains  zero  patterns,  and  therefore matches
          nothing.  (-f is specified by POSIX.)
   -Z, --null
          Output a zero byte (the ASCII NUL character) instead of
          the  character  that normally follows a file name.  For
          example, grep -lZ outputs a zero byte after  each  file
          name  instead  of the usual newline.  This option makes
          the output unambiguous, even in the  presence  of  file
          names  containing  unusual  characters  like  newlines.
          This  option  can  be  used  with  commands  like  find
          -print0,  perl  -0,  sort  -z,  and xargs -0 to process
          arbitrary file names, even those that  contain  newline
          characters.

আমি সুস্পষ্ট না হওয়ার জন্য দুঃখিত। দয়া করে সংশোধিত প্রশ্নটি দেখুন যা আমি আরও স্পষ্ট আশা করি।
চন্দ্র

@ চন্দ্র আপডেট হওয়া উত্তর, একই সাধারণ ধারণা, বিভিন্ন বিবরণ দেখুন।
terdon

ধন্যবাদ. আপনি আমার প্রশ্নের উত্তরটি আমার উদ্দেশ্যটির জন্য খুব স্পষ্ট এবং নিখুঁতভাবে দিয়েছেন। আমি আপনার উত্তর গ্রহণ করেছি।
চন্দ্র

6

জিএনইউ ফাইন্ডের সাথে (অর্থাত্ এমবেডড লিনাক্স বা সাইগউইনের অধীনে), আপনি -regexএই সমস্ত -pathওয়াইল্ডকার্ডগুলিকে একটি একক রেজেক্সে একত্রিত করতে ব্যবহার করতে পারেন ।

find . -regextype posix-extended \
     -type d -regex '\./(\..*|Music|Documents)' -prune -o \
     -type f -regex '.*(\.(bck|bak|backup)|~)' -print0 |
xargs -0 --no-run-if-empty trash-put

ফ্রিবিএসডি বা ওএসএক্সের -Eপরিবর্তে ব্যবহার করুন -regextype posix-extended


একটি দুর্দান্ত বিকল্প উত্তরের জন্য আপনাকে ধন্যবাদ। লজ্জার বিষয় যে আমি দুটি উত্তর গ্রহণ করতে পারি না।
চন্দ্র

3

( বা ) যুক্তি ব্যবহার করে -path ... -pruneসংযুক্ত একটি অভিব্যক্তিতে গ্রুপ করুন ।\( ... \)-o

find /somepath \( -path /a -prune -o \
                  -path /b -prune -o \
                  -path /c -prune \
               \) \
               -o -print

উদাহরণস্বরূপ হবে বারবার না ডিরেক্টরি বা বা অধীনে ফাইল /somepath/a, /somepath/bএবং /somepath/c

একাধিক ক্রিয়া ব্যবহার করে এখানে আরও নির্দিষ্ট উদাহরণ দেওয়া হল।

find / \( -path /dev -prune -o \
          -path /proc -prune -o \
          -path /sys -prune \
       \) \
       -o -printf '%p ' -exec cksum {} \;

1

এটি একটি প্রশ্নের চেয়ে বেশি শেল প্রশ্ন বলে মনে হচ্ছে find। একটি ফাইল ( -name dir1 -o -name dir2 ) -prune("" \ "না!) সহ আপনি সহজেই এটি করতে পারেন:

find ... $(< /path/to/file)

অনুসন্ধান কলটি নিজেই পরিবর্তন না করে ( eval findor আইএফএসে বা পরিবর্তন করে) এটি কেবল শ্বেত স্পেস ছাড়াই পথগুলির সাথে কাজ করে।

আপনি যদি ফাইলটি আরও সহজ রাখতে চান তবে আপনি একটি স্ক্রিপ্ট লিখতে পারেন।

# file content
dir1
dir2
dir3

# script content
#!/bin/bash
file=/path/to/file
# file may be checked for whitespace here
grep '[^[:space:]]' "$file" | { empty=yes
  while read dir; do
    if [ yes = "$empty" ]; then
      echo -n "( "
      empty=no
    else
      echo -n " -o "
    fi
    echo -n "-name ${dir}"
  done
  if [ no = "$empty" ]; then
    echo -n " ) -prune"
  fi; }

আর ব্যবহার করুন

find ... $(/path/to/script)

পরিবর্তে.


আমি সুস্পষ্ট না হওয়ার জন্য দুঃখিত। দয়া করে সংশোধিত প্রশ্নটি দেখুন যা আমি আরও স্পষ্ট আশা করি।
চন্দ্র

@chandra আমি দেখতে তন্ন তন্ন কিভাবে আপনার প্রশ্ন আরও পরিস্কার হল না আমি বুঝতে কি (এর তুচ্ছ replecement ছাড়া আমার সমাধান সঙ্গে একটি সমস্যা হতে পারে -nameদ্বারা path)।
হউক লেগেছে

আমার স্ক্রিপ্ট উপরে কাজ করে এবং আমি যা চাই তা করে does আমি কেবল জানতে চেয়েছিলাম \( -path "dir1" -o -path "dir2" ... -o -path "dirN" \) -pruneযে পুনরাবৃত্ত অনুসন্ধান থেকে নির্দিষ্ট ডিরেক্টরিগুলি বাদ দেওয়ার চেয়ে আরও ভাল উপায় ছিল কিনা find। আমি ফাইলগুলির মধ্যে কোনও কিছুর সন্ধান করছি না বরং কিছু নির্দিষ্ট ফাইল মুছতে এবং আমার অনুসন্ধানের পথে নির্দিষ্ট ডিরেক্টরি এড়িয়ে চলেছি। আপনার স্ক্রিপ্টটি কী চেষ্টা করছে তা আমি বুঝতে পারি না। সুতরাং, এটি আমাদের একটি ভুল যোগাযোগ আছে বলে মনে হচ্ছে। দুঃখিত। আসুন এটি এ ছেড়ে দিন।
চন্দ্র
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.