গ্লোব প্যাটার্ন থেকে পরিবর্তিত ভেরিয়েবলের সাথে ব্যাশ প্রতিস্থাপন


10

নীচের উদাহরণটি বিষয়টি ব্যাখ্যা করে। FILENAMEপ্রতিস্থাপন ব্যবহার করার সময় প্রতিলিপি হিসাবে প্রতিধ্বনিত হওয়া এবং অনুধাবন করার সময় কেন সঠিকভাবে মুদ্রিত হয়?

#!/bin/bash

FILEPATH_WITH_GLOB="/home/user/file_*"
FILENAME=$(basename "$FILEPATH_WITH_GLOB")
echo $FILENAME                #file_1234
echo ${FILENAME:1:5}          #ile_*   <---why is this not ile_1

উত্তর:


15
FILEPATH_WITH_GLOB="/home/user/file_*"

এখন, FILEPATH_WITH_GLOBরয়েছে/home/user/file_*

FILENAME=$(basename "$FILEPATH_WITH_GLOB")

FILENAMEরয়েছে file_*

echo $FILENAME                #file_1234

$FILENAMEতালিকার প্রেক্ষাপটে অচিরাচরিত হওয়ায়, এই বিস্তৃতিটি স্প্লিট + গ্লোব অপারেটরটির মধ্য দিয়ে চলেছে, সুতরাং এটি মেলানো ফাইলের তালিকায় প্রসারিত হবে: পরামিতি প্রসারণের পরে ফাইলের নাম তৈরি করা হয় ।

echo ${FILENAME:1:5}          #ile_*   <---why is this not ile_1

এটি এখনও তালিকার প্রসঙ্গে একটি অব্যক্ত প্যারামিটার সম্প্রসারণ, সুতরাং এখনও বিভক্ত + বিশ্বব্যাপী চলছে। তবে এখানে, ile_*প্যাটার্নটি কোনও ফাইলের সাথে মেলে না, তাই এটি তার পরিবর্তে নিজের কাছে প্রসারিত।

আপনি সম্ভবত এখানে যা চান তা হ'ল:

shopt -s nullglob # have globs expand to nothing when they don't match
set -- /home/user/file_* # expand that pattern into the list of matching 
                         # files in $1, $2...
for file do  # loop over them
  filename=$(basename -- "$file")
  printf '%s\n' "$filename" "${filename:1:5}"
done

অথবা আপনি এগুলিতে একটি অ্যারেতে রাখতে পারেন:

shopt -s nullglob
files=(/home/user/file_*)

যদি আপনি কেবল প্রথম ম্যাচটিই যত্নশীল হন বা আপনি জানেন যে কেবল একটি ম্যাচ রয়েছে তবে আপনি সেই ফাইলটিকে সেই হিসাবে উল্লেখ করতে পারেন $filesbashযা সাধারণত বিরক্তিকর আচরণ আছে যা $filesবিস্তৃতি ${files[0]}পরিবর্তে অ্যারে (ক আচরণ থেকে উত্তরাধিকারসূত্রে সব উপাদানের ksh, সংশোধন zsh), কিন্তু এখানে যে একবার একটি চেয়েছিলেন আচরণ হবে।


ব্যাখ্যার জন্য ধন্যবাদ. FILEPATH_WITH_GLOB=`echo /home/user/file_*` আপনার ব্যাখ্যা পরে একটি workaround করতে পরিচালিত ।
TheMeaningfulEngineer

@ অ্যালান, এটির সমাধানের এটিই ভুল উপায়। আপনি এখানে একটি অ্যারে ব্যবহার করতে চান। উভয় ক্ষেত্রেই আমার উদাহরণঃ ($ 1, $ 2 ...) হিসেবে অবস্থানগত পরামিতি বা bashমত বিন্যাস: files=(/home/user/file_*)
স্টাফেন চেজেলাস

(এবং সমস্ত আপার-কেস ভেরিয়েবলগুলি সত্যই পরিবেশের ভেরিয়েবলের জন্য সংরক্ষিত echoহওয়া উচিত , স্বেচ্ছাসেবী তথ্যের জন্য ব্যবহার করা উচিত নয়, তালিকা প্রসঙ্গে ভেরিয়েবলগুলি অচিরাচরিত রাখা উচিত নয়)।
স্টাফেন চেজেলাস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.