বিপুল সংখ্যক ফাইল রয়েছে এমন কোনও ডিরেক্টরিতে বাশ-এ ট্যাব সমাপ্তি অক্ষম করবেন?


19

আমি প্রচুর সংখ্যক ফাইল নিয়ে কাজ করছি, যা আমি একটি ডিরেক্টরিতে রাখি। আমি যখনই সেই ডিরেক্টরিটিতে যাই এবং দুর্ঘটনাক্রমে Tabদু'বার টিপতাম তখন প্যাটার্নের সাথে মেলে এমন ফাইলগুলি দেখাতে খুব বেশি সময় লাগে (এক মিনিটেরও বেশি হতে পারে) এবং আমি এই আচরণে বেশ বিরক্ত হয়েছি।

উদাহরণস্বরূপ, আমার ডিরেক্টরি কাঠামোটি হ'ল:

my-project/
├── docs/
├── data/        <---- contains around 200k files.
└── analyser/

যেহেতু আমি এখনও সমাপ্তি পছন্দ করি, তবে কি কেবলমাত্র data/ডিরেক্টরিতে এই বৈশিষ্ট্যটি অক্ষম করতে হবে ? 5 সেকেন্ডের জন্য নির্ধারিত টাইমআউট, বা কোনও স্ক্রিপ্ট যা নির্দিষ্ট ডিরেক্টরিতে স্বয়ংক্রিয়ভাবে সমাপ্তি স্যুইচ করে?


আপনি কি zsh এ পরিবর্তন করতে চান? (বাশে এটি সম্ভব কিনা তা আমি জানি না z আমি জানি এটি zsh এ সম্ভব, তবে এটি সহজ হতে পারে না, আমি চেক করিনি))
গিলস 'অশুভ হওয়া বন্ধ করুন'

উত্তর:


9

এটি নিখুঁত নয়, তবে তারপরে আবারও বাশ সম্পূর্ণ হওয়া বেশ জটিল জিনিস ...

খুব সহজ উপায় হ'ল পার-কমান্ডের ভিত্তিতে FIGNORE, আপনি যা করতে পারেন তার চেয়ে কিছুটা নমনীয় :

 complete -f -X "/myproject/data/*" vi

এটি স্বয়ংক্রিয়রূপে নির্দেশ দেয় যে viফাইলগুলির জন্য এবং -Xফিল্টারটির সাথে মিলে থাকা নিদর্শনগুলি অপসারণের জন্য এটি সম্পূর্ণ । নেতিবাচক দিকটি হ'ল প্যাটার্নটি স্বাভাবিক করা হয় না, তাই ../dataএবং প্রকরণগুলি মেলে না।

পরবর্তী সেরা জিনিসটি একটি কাস্টম PROMPT_COMMANDফাংশন হতে পারে :

# associative arrays of non-autocomplete directories
declare -A noacdirs=([/myproject/data]=1 )

function _myprompt {
    [[ -n "${noacdirs[$PWD]}" ]] && {
       echo autocomplete off
       bind 'set disable-completion on'
    } || {
       echo autocomplete on
       bind 'set disable-completion off'
    }
} 

PROMPT_COMMAND=_myprompt

আপনি ডিরেক্টরিতে থাকলে এটি সম্পূর্ণরূপে অক্ষম করে (পুরোপুরি), তবে এটি কেবলমাত্র সেই ডিরেক্টরিতে থাকা ফাইল নয় প্রতিটি পথের জন্য এটি অক্ষম করে।

এটি নির্ধারিত পাথের জন্য বেছে বেছে এটি অক্ষম করা আরও সাধারণভাবে কার্যকর হবে তবে আমি বিশ্বাস করি যে একটিমাত্র উপায় হ'ল একটি ডিফল্ট সমাপ্তি ফাংশন (ব্যাশ-৪.১ এবং পরে সহ complete -D) এবং প্রচুর গোলমাল।

এটি আপনার পক্ষে কাজ করা উচিত তবে এতে অনিচ্ছাকৃত পার্শ্ব প্রতিক্রিয়া থাকতে পারে (অর্থাত্ কিছু ক্ষেত্রে প্রত্যাশিত সমাপ্তির পরিবর্তন):

declare -A noacdirs=([/myproject/data]=1 )

_xcomplete() {
    local cur=${COMP_WORDS[COMP_CWORD]} # the current token

    name=$(readlink -f "${cur:-./}")  # poor man's path canonify
    dirname=$(dirname "$name/.")

    [[ -n "${noacdirs[$dirname]}" ]] && {
        COMPREPLY=( "" )   # dummy to prevent completion
        return
    }
    # let default kick in
    COMPREPLY=()
}

complete -o bashdefault -o default -F _xcomplete vi

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

আমি বিশ্বাস করি এর সাথে সাধারণ পদ্ধতির সাথে complete -Dপ্রতিটি কমান্ডের সমাপ্তির সাথে সাথে সম্পূর্ণরূপে ফাংশন যুক্ত করা হয়। একটি যুক্ত করতেও পারে complete -E(ইনপুট বাফার ফাঁকা থাকাকালীন কমান্ডের নাম সম্পূর্ণ হওয়া)।


আপডেট এখানে PROMPT_COMMANDএবং সমাপ্তির ফাংশন সমাধানগুলির একটি সংকর সংস্করণ রয়েছে , আমি মনে করি এটি বুঝতে এবং হ্যাক করা কিছুটা সহজ:

declare -A noacdirs=([/myproject/data]=1 [/project2/bigdata]=1)

_xcomplete() {
    local cmd=${COMP_WORDS[0]}
    local cur=${COMP_WORDS[COMP_CWORD]} # the current token

    [[ -z "$cur" && -n "$nocomplete" ]] && {
        printf "\n(restricted completion for $cmd in $nocomplete)\n"  
        printf "$PS2 $COMP_LINE"
        COMPREPLY=( "" )   # dummy to prevent completion
        return
    }
    COMPREPLY=()       # let default kick in
}

function _myprompt {
    nocomplete=
    # uncomment next line for hard-coded list of directories
    [[ -n "${noacdirs[$PWD]}" ]] && nocomplete=$PWD
    # uncomment next line for per-directory ".noautocomplete"
    # [[ -f ./.noautocomplete ]] && nocomplete=$PWD
    # uncomment next line for size-based guessing of large directories
    # [[ $(stat -c %s .) -gt 512*1024 ]] && nocomplete=$PWD
} 

PROMPT_COMMAND=_myprompt
complete -o bashdefault -o default -F _xcomplete vi cp scp diff

nocompleteআপনি যখন কনফিগার করা ডিরেক্টরিগুলির মধ্যে একটি প্রবেশ করেন তখন এই প্রম্পট ফাংশনটি পরিবর্তনশীল সেট করে । পরিবর্তিত সমাপ্তির আচরণটি কেবল তখনই শুরু হয় যখন সেই পরিবর্তনশীলটি শূন্য থাকে এবং কেবল যখন আপনি খালি স্ট্রিং থেকে সম্পূর্ণ করার চেষ্টা করেন, এভাবে আংশিক নামগুলি সম্পূর্ণ করার অনুমতি দেয় ( -z "$cur"সম্পূর্ণরূপে সম্পূর্ণতা রোধ করার শর্তটি সরিয়ে দেয়)। printfনীরব অপারেশনের জন্য দুটি লাইন মন্তব্য করুন ।

অন্যান্য বিকল্পের মধ্যে প্রতি ডিরেক্টরি অন্তর্ভুক্ত থাকে .noautocomplete পতাকা যা আপনি touchডিরেক্টরিতে ডিরেক্টরিতে পারেন প্রয়োজন হিসাবে; এবং জিএনইউ ব্যবহার করে ডিরেক্টরি আকার অনুমান করা stat। আপনি এই তিনটি বিকল্পের যে কোনও বা সমস্ত ব্যবহার করতে পারেন।

(দ্য stat পদ্ধতিটি কেবলমাত্র একটি অনুমান , এর তালিকাভুক্ত ডিরেক্টরি আকারটি এর বিষয়বস্তুগুলির সাথে বৃদ্ধি পায়, এটি একটি "উচ্চ জলের চিহ্ন" যা কোনও প্রশাসনিক হস্তক্ষেপ ছাড়াই ফাইলগুলি মুছে ফেলা হলে সাধারণত সঙ্কুচিত হবে না a সম্ভাব্য বৃহতের প্রকৃত সামগ্রী নির্ধারণের চেয়ে সস্তা ডিরেক্টরি। ফাইলের প্রতি যথাযথ আচরণ এবং বর্ধন অন্তর্নিহিত ফাইল সিস্টেমের উপর নির্ভর করে I আমি এটি লিনাক্স ext2 / 3/4 সিস্টেমে কমপক্ষে একটি নির্ভরযোগ্য সূচক পাই))

খালি সমাপ্তি ফিরে আসার পরেও বাশ একটি অতিরিক্ত স্থান যুক্ত করে (এটি কেবলমাত্র একটি লাইনের শেষে সম্পূর্ণ করার সময় ঘটে)। তুমি যোগ করতে পার-o nospaceএটি completeরোধ কমান্ডটিতে করতে ।

আর একটি নিগল হ'ল আপনি যদি একটি টোকেন এবং হিট ট্যাব শুরু করার জন্য কার্সারটিকে ব্যাক আপ করেন তবে ডিফল্ট সমাপ্তি আবার শুরু হবে। এটি একটি বৈশিষ্ট্য বিবেচনা করুন ;-)

(অথবা আপনি ${COMP_LINE:$COMP_POINT-1:1}যদি ওভার ইঞ্জিনিয়ারিং পছন্দ করেন তবে আপনি আশেপাশে ফুট করতে পারেন, তবে আমি খুঁজে পাচ্ছি যে আপনি যখন ব্যাকআপ নেবেন এবং কোনও কমান্ডের মাঝখানে সম্পূর্ণ করার চেষ্টা করবেন তখন ব্যাশ নিজেই সম্পূর্ণরূপে পরিবর্তনশীলগুলি সেট করতে ব্যর্থ হয়))


6

আপনার যদি dataডিরেক্টরির একটি নির্দিষ্ট প্রত্যয় ফাইল রয়েছে, যেমন .out , তাহলে আপনি আপনার সেট করতে পারেন bashপরিবর্তনশীল FIGNOREথেকে".out" এবং এই উপেক্ষা করা হবে। যদিও ডিরেক্টরিগুলির নামগুলিও ব্যবহার করা সম্ভব, এটি বর্তমানের চলমান ডিরেক্টরি ডিরেক্টরিতে সহায়তা করে না।

উদাহরণ:

রেড 1 এইচডিডি সহ শারীরিক হোস্টে হাজার হাজার 100 কেবি পরীক্ষা ফাইল তৈরি করুন:

for i in {1..200000}; do dd if=/dev/urandom bs=102400 count=1 of=file$i.json; done

bashভেরিয়েবল সেট করুন :
$ FIGNORE=".json"

পরীক্ষার ফাইলটি তৈরি করুন:
$ touch test.out

এ পরীক্ষা 5,000 ফাইলগুলি:

$ ls *.json|wc -l
5587
$ vi test.out

ভি এবং একক এর মধ্যে উপস্থিত tabহওয়ার আগে কোনও বিলম্ব নেই test.out

50,000 ফাইল এ পরীক্ষা করুন :

$ ls *.json|wc -l
51854
$ vi test.out

একক ট্যাব test.outপ্রদর্শিত হওয়ার আগে দ্বিতীয় বিলম্বের একটি ভগ্নাংশ তৈরি করে ।

এ পরীক্ষা করুন 200,000 ফাইলগুলি:

$ ls *.json|wc -l
bash: /bin/ls: Argument list too long
$ ls | awk 'BEGIN {count=0} /.*.json/ {count++} END {print count}'
200000
$ vi test.out

Vi এবং এককটির মধ্যে 1 সেকেন্ডের বিলম্ব উপস্থিত tabহওয়ার আগে test.out

তথ্যসূত্র:

ম্যান বাশ থেকে অংশ

FIGNORE
              A  colon-separated  list  of  suffixes to ignore when performing filename completion (see READLINE below).  A filename whose suffix matches one of the entries in FIGNORE is
              excluded from the list of matched filenames.  A sample value is ".o:~".

1
সাহায্য করবে না, dir w / প্রায় ~ 100k ফাইল তৈরি করার চেষ্টা করুন। তাহলে আমি করি $ vi <tab><tab>, যাইহোক এটি অনেক সময় নেয়। : \
নীজোদ

এখনও সমস্যাটি সমাধান করেন না, ধরুন আমার কাছে 100k .jsonফাইল এবং একটি একক পাঠ্য ফাইলের নাম foo.txt। চালু FIGNORE='.json'হচ্ছে, আমি টাইপ করছি $ vi <tab>এবং এখনও আমার অর্ধ মিনিট অপেক্ষা করতে হবে যাতে এটি আমার সম্পূর্ণ করে $ vi foo.txt। --- আসল পরিস্থিতি আমি এই ডিয়ারের মধ্যে ফাইলের ধরণগুলি সম্পাদনা করব না, বা মিশ্রিত করব না, তবে যদি আমি চালু করি FIGNOREএবং (দুর্ঘটনাক্রমে) ট্যাবটি টিপবই, তবে আমার কীবোর্ডটি এমন কোনও কিছুর ইঙ্গিত ছাড়াই দীর্ঘকাল স্থায়ী হয়ে যাবে Display all 188275 possibilities? (y or n), যা আমাকে বলে আমি আমার কীবোর্ড ফিরে পেতে পারেন যে।
নিজোদ

@neizod - দুঃখিত, আমি ডাইরেক্টরি স্তরে কাজ করার জন্য ডুমুরকে পেতে অনেক পরিস্থিতিতে চেষ্টা করেছিলাম, কোনও লাভ হয়নি। আমি অনুমান করি একটি কাস্টম সমাধান প্রয়োজন, বা আপনি কেবল সেই হোস্টের উপর বাশ সম্পূর্ণ করতে অক্ষম করুন, বা আমাদের বোন সাইট গিলস উল্লিখিত zsh সমাধানটি বিশদভাবে চেষ্টা করে দেখুন।
geedoubleya

দুঃখিত, এটি আপনার সিস্টেমে মাত্র 1 সেকেন্ড, এটি আমার সিস্টেমে প্রায় আধা মিনিটের কাছাকাছি। সুতরাং আমি অনুমান করি যে আমি এই সমাধানটি কাজ করার জন্য একটি নতুন পিসি কিনব।
নিজোদ

0

অনুমান করুন যে আপনি এটি চান (@ মিঃ স্পুর্যাটিকের কাছ থেকে কিছু কোড ধার করা)

মনে রাখবেন এটি আপনাকে পুরো পাথ ব্যবহার করে টিএব টিপতে বাধা দেয় না (উদাঃ vim /directory/contains/lots/files<tab><tab>

function cd() {
  builtin cd "$@"
  local NOCOMPLETION=( "/" "/lib" )
  local IS_NOCOMPLETION=0
  for dir in "${NOCOMPLETION[@]}"
  do
    echo $dir
    if [[ $(pwd) == "$dir" ]]
    then
      echo "disable completion"
      bind "set disable-completion on"
      IS_NOCOMPLETION=1
      return
    fi                                                                                                                                                                                              
  done
  if [[ $IS_NOCOMPLETION -eq 0 ]]
  then
    echo "enable completion"
    bind "set disable-completion off"
  fi
}  

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