ব্যাশের একটি দৃ way় উপায় হ'ল একটি অ্যারেতে প্রসারিত করা এবং কেবল প্রথম উপাদানটি আউটপুট করা:
pattern="*.txt"
files=( $pattern )
echo "${files[0]}" # printf is safer!
(আপনি এমনকি ঠিক করতে পারেন echo $files
, একটি অনুপস্থিত সূচককে [0] হিসাবে গণ্য করা হয়))
ফাইলের নামগুলি প্রসারিত করার সময় এটি স্পেস / ট্যাব / নিউলাইন এবং অন্যান্য মেটাচ্যাকার্টারগুলি নিরাপদে পরিচালনা করে। নোট করুন যে কার্যকরভাবে লোকেল সেটিংস "প্রথম" কী তা পরিবর্তন করতে পারে।
আপনি এটিও ব্যাশ সমাপ্তির কার্যক্রমে ইন্টারেক্টিভভাবে করতে পারেন :
_echo() {
local cur=${COMP_WORDS[COMP_CWORD]} # string to expand
if compgen -G "$cur*" > /dev/null; then
local files=( ${cur:+$cur*} ) # don't expand empty input as *
[ ${#files} -ge 1 ] && COMPREPLY=( "${files[0]}" )
fi
}
complete -o bashdefault -F _echo echo
এটি _echo
ফাংশনটি echo
কমান্ডের সাথে যুক্তিগুলি সম্পূর্ণ করতে বাধ্য করে (সাধারণ সম্পূর্ণরূপে ওভাররাইডিং)। উপরের কোডে একটি অতিরিক্ত "*" যুক্ত করা হয়েছে, আপনি কেবলমাত্র একটি আংশিক ফাইলের নামটিতে ট্যাবটি হিট করতে পারেন এবং আশা করি সঠিক জিনিসটি ঘটবে।
কোডটি সেট বা ধরে নেওয়ার পরিবর্তে কোডটি কিছুটা বিশৃঙ্খলাযুক্ত nullglob
( shopt -s nullglob
) আমরা পরীক্ষা compgen -G
করে কিছু বিশ্বজুড়ে কিছু ম্যাচ প্রসারিত করতে পারি, তারপরে আমরা নিরাপদে একটি অ্যারেতে প্রসারিত করি এবং শেষ পর্যন্ত সম্পূর্ণ সেট করি যাতে উদ্ধৃতি শক্তিশালী।
আপনি আংশিকভাবে এটিকে (প্রোগ্রামগতভাবে একটি গ্লোব প্রসারিত করতে পারেন ) compgen -G
বাশের সাথে করতে পারেন, তবে এটি শক্তিশালী নয় কারণ এটি স্টাডআউটকে অকার্যকর করে তোলে।
যথারীতি, সমাপ্তি বরং ভরাট, এটি পরিবেশের ভেরিয়েবল সহ অন্যান্য জিনিসের সমাপ্তি ভঙ্গ করে ( ডিফল্ট আচরণ অনুকরণের বিশদটির জন্য এখানে_bash_def_completion()
ফাংশনটি দেখুন )।
আপনি কেবলমাত্র compgen
একটি সমাপ্তির ফাংশনের বাইরেও ব্যবহার করতে পারেন :
files=( $(compgen -W "$pattern") )
একটি বিষয় লক্ষণীয় যে "~" কোনও গ্লোব নয়, এটি বাশ দ্বারা বিস্তারের পৃথক পর্যায়ে পরিচালিত হয়, যেমন $ ভেরিয়েবল এবং অন্যান্য বিস্তৃতি। compgen -G
কেবল ফাইলের নামটি গ্লোব্বিং করে compgen -W
তবে সম্ভবত ব্যাশের ডিফল্ট সম্প্রসারণ সমস্ত দেয়, সম্ভবত খুব বেশি বিস্তৃত (সহ ``
এবং $()
)। ভিন্ন -G
, -W
হয় নিরাপদে উদ্ধৃত (আমি অসমতা ব্যাখ্যা না করতে পারেন)। যেহেতু এর উদ্দেশ্য -W
হ'ল এটি টোকেনগুলি প্রসারিত করে, এর অর্থ এটি এমন একটি ফাইল উপস্থিত না থাকলেও এটি "a" থেকে "a" প্রসারিত করবে, সুতরাং এটি সম্ভবত আদর্শ নয়।
এটি বোঝা সহজ, তবে এতে অযাচিত পার্শ্ব-প্রতিক্রিয়া থাকতে পারে:
_echo() {
local cur=${COMP_WORDS[COMP_CWORD]}
local files=( $(compgen -W "$cur") )
printf -v COMPREPLY %q "${files[0]}"
}
তারপর:
touch $'curious \n filename'
echo curious*
tab
printf %q
মানগুলি নিরাপদে উদ্ধৃত করার জন্য ব্যবহারটি নোট করুন ।
একটি চূড়ান্ত বিকল্প হ'ল জিএনইউ ইউটিলিটিগুলির সাথে 0-সীমাবদ্ধ আউটপুট ব্যবহার করা ( ব্যাশ এফএকিউ দেখুন ):
pattern="*.txt"
while IFS= read -r -d $'\0' filename; do
printf '%q' "$filename";
break;
done < <(find . -maxdepth 1 -name "$pattern" -printf "%f\0" | sort -z )
এই বিকল্পটি আপনাকে বাছাই করার আদেশের উপরে আরও কিছুটা নিয়ন্ত্রণ দেয় (গ্লোব সম্প্রসারণের সময় ক্রমটি আপনার লোকেলের সাপেক্ষে থাকবে / LC_COLLATE
এবং কেসটি ভাঁজও হতে পারে ) তবে অন্যথায় এ জাতীয় ছোট সমস্যাটির জন্য বরং একটি বড় হাতুড়ি ;-)