কমান্ড লাইনে * থেকে বাদ দিন


14

এমন প্রচুর পরিস্থিতি রয়েছে যেখানে একটি ব্যবহার *কার্যত অনিবার্য - যেমন rm -rf *একটি ফোল্ডারে যা হাজার হাজার সাব-ফোল্ডার এবং ফাইল ধারণ করে।

তবে আপনি যদি rmকমান্ড থেকে কেবল একটি বা দুটি ফাইল বা ফোল্ডার বাদ দিতে চান ? আমি প্রায় আমার পথ googled এবং শুধুমাত্র এখানেfind . -depth -not \( -name 'one' -o -name 'two' \ -o -name 'three' \) -exec rm {} \; বর্ণিত মত জটিল জটিল সমাধান পেয়েছি ।

কোনও সহজ উপায়ে এটি করার কোনও সম্ভাবনা আছে - সেই পথটি ছাড়াই find? যেমন rm -rf --exclude='one' --exclude='two' --exclude='three' *আরএসআইএনসি তে নাকি ঠিক rm -rf -e 'one','two','three' *?

হয়তো এমনকি একটি সাধারণ সম্ভাবনা থেকে কিছু বাদ দেওয়ার *(তাই অন্যান্য কমান্ডের মত cp, mv... তাদের নিজস্ব বাস্তবায়ন হবে না)? এরকম কিছু *{'one','two','three'}নাকি?


3
আপনি যদি কেবল একটি বা দুটি ফাইল রাখতে চান তবে সবচেয়ে সহজ ও সহজ উপায় হ'ল এই ফাইলগুলিকে অন্য জায়গায় সরিয়ে নেওয়া, সমস্ত ফাইল মুছে ফেলা এবং আপনি যে ফাইলগুলি রেখে এসেছেন তা সরিয়ে নেওয়া। আপনি অনেক একাধিক ফাইল আমি ব্যবহার করেন রাখতে চান findসঙ্গে --deleteবিকল্প (নির্বাহ করার কোন প্রয়োজন rmপ্রতিটি ফাইল জন্য। যে অপ্রয়োজনীয় ওভারহেড যায়)।
হেনেস

এটি একটি সম্ভাবনা হবে, তবে এটি আমি উল্লেখ করা হিসাবে প্রায় বিস্তৃত। আমি জানি আমি কমান্ডগুলিকে এরকম কোনও কিছুর সাথে একত্রিত করতে mv -t /tmp one two three && rm -rf * && mv -t . /tmp/one /tmp/two /tmp/threeপারি, তবে আমি কোনও সমাধানটি পছন্দ করে এটিকে কিছু থেকে স্পষ্টতই বাদ দেওয়ার সম্ভাবনা প্রদান করব *। অবশ্যই এমন পরিস্থিতি থাকবে যেখানে ফাইলগুলি অন্য গন্তব্যে সরিয়ে নেওয়া বা অনুলিপি করা কোনও বিকল্প হবে না।
ডেভিড

2
এটি হ'ল এজন্য আমি উত্তর হিসাবে এটি পোস্ট করি নি। নিছক জিনিসগুলি করার জটিল উপায় হিসাবে (তিনটি খুব সাধারণ কমান্ড বনাম একটি আরও জটিল কিছু)। আমি আরএম এর সাথে মিশে জটিলতা ঘৃণা করি।
হেনিস

উত্তর:


33

ব্যাশ জন্য শেল বিকল্প নামক নেই extglobযে ডিফল্টরূপে নিষ্ক্রিয় মান শেল সিনট্যাক্স সাথে সামঞ্জস্যের রাখা। Extglob মত অতিরিক্ত অপারেটার দ্বারা সিনট্যাক্স সম্পূরক !(), ?(), @()এবং কিছু আরও অনেক কিছু।

চালু করতে extglobটাইপ করুন shopt -s extglob। বর্তমান ব্যবহারকারীর ধরণের জন্য এটি চালু রাখতে echo 'shopt -s extglob' >> ~/.bashrc

আরএম উদাহরণের জন্য: extglobআপনি ব্যবহার করতে পারেন সহ

rm -rf !(one|two|three)

একটি ভাল সমাধান বলে মনে হচ্ছে, তবে আমি যখনই বর্ণিতটির মতো পরিস্থিতির মধ্যে যাই তখনও আমি এটিকে চালু এবং বন্ধ করতে চাই না।
ডেভিড

3
@ ডেভিড: আপনি shoptজিনিসটি আপনার মধ্যে couldুকতে ~/.bashrcপারেন, এটি ক্ষতি করতে পারে না।
এনজোটিব

যদি আমি এটি সঠিকভাবে পাই তবে এক্সটগ্লোব বিকল্পটি একেবারে প্রভাব পরিবর্তন করে না *, বরং পরিবর্তে অনুরূপ সূচকগুলি যুক্ত করে (এর মতো !) অতিরিক্ত ফাংশন রয়েছে? সেক্ষেত্রে এটি একটি সুন্দর সমাধান হবে।
ডেভিড

1
@ ডেভিড: হুবহু
চোরোবা

1
@ ডেভিড স্ট্যান্ডার্ড শেল সিনট্যাক্সের সাথে সামঞ্জস্য রাখতে । আচরণের পরিবর্তন হতে পারে এমন অন্যান্য পরিস্থিতিও সম্ভবত রয়েছে।
জাগ্রত

4

আমি তৈরি করেছি ছাড়া ঠিক যে জন্য (sry যে আমি এখনো ডকুমেন্টেশন যুক্ত করতে সক্ষম ছিল না)।

আমি আপনার নীচের মত একটি ফোল্ডার আছে:

$ ls
a b c d

টাইপিং except b dআপনাকে দেবে aএবংc

$ except b d
ac

এখন আপনি এটি পাইপ করতে পারেন rm

except b d | xargs -0 rm

এটি মনে রাখা শক্ত হতে পারে, তবে কেন কেবল এইগুলির উপরে কেবল একটি স্ক্রিপ্ট তৈরি করবেন না rm-except:

#!/usr/bin/env bash

except "$@" | xargs -0 rm

একইভাবে সহজ ls-except:

#!/usr/bin/env bash

except "$@" | xargs -0 ls

3
এটি দুর্দান্ত, তবে আপনি যখন এক্সট্লোব্লব সম্পর্কে জানবেন তখন সত্যিই প্রয়োজন নেই - Askubuntu.com/a/329233/138369
ডেভিড

1

এক্সট্লোব এর বিকল্প হিসাবে (যদিও এটি খুব ভাল উত্তর এবং প্রত্যেকেরই shopt -s extglob globstarতাদের .bashrc এ থাকা উচিত ), আপনি LO গ্লোবগনার গ্লোবাল ভেরিয়েবল ব্যবহার করতে পারেন । ধরা যাক আপনি 'foo.txt' এবং 'বার baz.txt' ব্যতীত প্রতিটি ফাইল পেতে চান:

GLOBIGNORE=foo.txt:'bar baz.txt'

... তবে এটি শেল বিকল্পটি চালু করবে dotglob, যার অর্থ *বিন্দু দিয়ে শুরু হওয়া ফাইলগুলির সাথে মিলবে (যা সাধারণত লুকানো থাকে)। সুতরাং আপনার আসলে দুটি কমান্ডের প্রয়োজন:

GLOBIGNORE=foo.txt:'bar baz.txt'
shopt -u dotglob

যেহেতু এটি বিশ্বব্যাপী পরিবর্তনশীল, এটি লগ আউট বা এর মাধ্যমে LO গ্লোবস্টার আনসেট না হওয়া অবধি আপনি যে সমস্ত গ্লোব ব্যবহার করবেন তা প্রভাবিত করবে

GLOBIGNORE=

এটি কেবল ভেরিয়েবলের কাছে আক্ষরিক স্ট্রিংগুলিতে কাজ করবে। LO GLOBIGNORE সেট করে এবং এই আদেশগুলির মধ্যে পার্থক্যটি দেখে আপনি কী বোঝাতে চাইছেন:

printf '%s\n' *
printf '%s\n' ./*
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.