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


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_*)

যদি আপনি কেবল প্রথম ম্যাচটিই যত্নশীল হন বা আপনি জানেন যে কেবল একটি ম্যাচ রয়েছে তবে আপনি সেই ফাইলটিকে সেই হিসাবে উল্লেখ করতে পারেন $files। bashযা সাধারণত বিরক্তিকর আচরণ আছে যা $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.