সফল হলে কোনও কমান্ডের আউটপুট পাইপ করুন


14
INPUT_FILE=`ls -rt $MY_DIR/FILE.*.xml | head -1 | xargs basename`

আমি head -1প্রথম কমান্ডটি সফল হলেই দ্বিতীয় কমান্ডটি কার্যকর করতে চেয়েছিলাম । আমি এই আদেশটি কীভাবে উন্নত করব?


সফল বলতে কী বোঝ? lsব্যর্থ হবে না।
মেটেও

2
কোনও গানের ফাইল না থাকলে গ্লোব ব্যর্থ হতে পারে।
ট্রিপলি

উত্তর:


8

এটা চেষ্টা কর:

INPUT_FILE=`ls -rt "$MY_DIR"/FILE.*.xml | head -1 | xargs -r basename`

পাসিং সেটির উপরে ফ্ল্যাগ লাগাতে শুধুমাত্র চালানোর জন্য কারণ হবে যদি অন্তত একটি আইটেম মান ইনপুট থেকে (সার্চ )।xargs-rbasenamehead -1

head -1 চলবে তবে আপনি এটি থেকে কোনও আউটপুট দেখতে বা ক্যাপচার করতে পারবেন না।

এছাড়াও, আপনি যদি ব্যবহারকারীকে কোনও ত্রুটি আউটপুট দেখতে না চান তবে lsআপনি lsএর স্ট্যাডার স্ট্রিমটিতে পুনর্নির্দেশ করতে পারেন /dev/null

INPUT_FILE=`ls -rt "$MY_DIR"/FILE.*.xml 2> /dev/null | head -1 | xargs -r basename`

এছাড়াও লক্ষ করুন যে আমি চারপাশে উদ্ধৃতি চিহ্ন যুক্ত করেছি $MY_DIR। এইভাবে, $MY_DIRস্পেস থাকলে কমান্ডটি ব্যর্থ হবে না ।

আপনি যদি কোনও আধুনিক শেল যেমন বাশ ব্যবহার করছেন তবে আপনার $( )ব্যাকটিকের পরিবর্তে ক্যাপচার শেল ব্যবহার করা উচিত । আপনার ভেরিয়েবলের স্টাইল পরিবর্তন করাও বিবেচনা করা উচিত। আপনার সাধারণত স্ক্রিপ্টগুলিতে সমস্ত-বড় হাতের পরিবর্তনশীল নামগুলি এড়ানো উচিত। এই স্টাইলটি সাধারণত সংরক্ষিত এবং পরিবেশগত পরিবর্তনশীলগুলির জন্য সংরক্ষিত।

input_file=$(ls -rt "$my_dir"/FILE.*.xml 2> /dev/null | head -1 | xargs -r basename)

কোনও ফাইল না থাকলে এই b0rk না?
মেল বয়েস

আসলে: ls -rt GLOB 2>/dev/null | head -n1 | xargs -r basenameকাজ করে।
মেল বয়েস

@ মেলবয়েস: আমি আমার উত্তরে এটি যুক্ত করেছি। ধন্যবাদ।

ls ফাইলের তথ্য ইন্টারেক্টিভভাবে দেখার জন্য একটি সরঞ্জাম। এর আউটপুট মানুষের জন্য ফর্ম্যাট করা হয়েছে এবং স্ক্রিপ্টগুলিতে বাগ তৈরি করবে। গ্লোব ব্যবহার করুন বা তার পরিবর্তে সন্ধান করুন। কেন বুঝতে পারছেন: mywiki.wooledge.org/ পার্সিংএলস
সিনেমালি

@ সিনেল্লি: এটা সত্য। আমি শুধু প্রশ্নের উত্তর দিচ্ছিলাম।

9

পাইপ লাইনে, সমস্ত কমান্ডগুলি একের পর এক হয় না, একই সাথে শুরু হয় এবং একই সাথে চালিত হয়। সুতরাং আপনি আউটপুট কোথাও সঞ্চয় করতে হবে।

if ls_output=$(ls -rtd -- "$MY_DIR"/FILE.*.xml); then
  first_file=$(printf '%s\n' "$ls_output" | head -n 1)
  first_file_name=$(basename -- "$first_file")
fi

মনে রাখবেন যে এটি ধরে নিয়েছে ফাইলের নামগুলিতে নতুন লাইন অক্ষর নেই। ব্যবহারের xargsফলে ফাঁকা অক্ষর, একক এবং ডাবল উদ্ধৃতি এবং ব্যাকস্ল্যাশগুলির সমস্যাও বোঝায়। ভেরিয়েবলগুলি অব্যক্ত রেখে যাওয়া অর্থ স্থান, ট্যাব এবং ওয়াইল্ডকার্ড অক্ষরগুলির সাথে সমস্যা। ভুলে যাওয়া --মানে ফাইল নামগুলির সাথে শুরু হওয়া সমস্যা -

zshঅক্ষরগুলির উপর এই নিষেধাজ্ঞাগুলি ছাড়াই প্রাচীনতম ফাইলের ভিত্তি নামটি পেতে (কোনও কমান্ডের সাথে যুক্তির সীমিত আকারের সমস্যাও এড়ানো হয়):

 first_file_name=($MY_DIR/FILE.*.xml(Om[1]:t))

যদি কোনও মিল নেই, তবে সেই কমান্ডটি ব্যর্থ হবে এবং স্ক্রিপ্টটি বাতিল করে দেবে। আপনি এটি করতে পারেন:

 first_file_name=($MY_DIR/FILE.*.xml(NOm[1]:t))

কোন ক্ষেত্রে first_file_nameঅ্যারেতে 1 টি মিল থাকে বা যদি না থাকে তবে 0 থাকে। তারপরে আপনি এটি করতে পারেন:

 if (($#first_file_name)); then
    printf 'Match: %s\n' $first_file_name
 else
    echo >&2 No match
 fi

4

একটি ডিরেক্টরিতে সর্বশেষ পরিবর্তিত ফাইলটি সন্ধান করুন:

latest() {
  local file path=${1:-.} ext=${2-} latest
  for file in "${path%/}"/*"$ext"; do 
    [[ $file -nt $latest ]] && latest=$file
  done
  [[ $latest ]] && printf '%s\n' "$latest"
}

ব্যবহার: latest [directory/path/ [.extension]]

কল করার পরিবর্তে basenameপ্যারামিটার সম্প্রসারণ ব্যবহার করুন।

in_file=$(latest in/my/dir .xml)
base_fn=${in_file##*/} base_fn=${base_fn%.*}

এই বিষয়বস্তু সহ একটি ডিরেক্টরিতে:

foo.xml bar.xml baz.xml newest.xml

বেস_ফন ভেরিয়েবলের সামগ্রীগুলি হ'ল: newest

আপনার অনুরোধের উদ্দেশ্যটি পরিবেশন করতে এটি সঠিকভাবে ব্যবহার করতে:

check_dir=/path/to/check
check_ext=.xml
if in_file=$(latest "$check_dir" "$check_ext"); then
  base_fn=${in_file##*/} base_fn=${base_fn%.*}
else
  printf '%s\n' "No file found in $check_dir" >&2
fi

সম্পাদনা: প্রশ্নের পর্যালোচনা করার পরে, আমি বুঝতে পেরেছি যে lsপ্রশ্নাবলীতে কমান্ডটি একটি ডিরেক্টরিতে প্রাচীনতম ফাইল সন্ধান করছে । এই একই ফাংশনটির নাম পরিবর্তন করা যেতে পারে oldestএবং [[ $file -ot $oldest ]] && oldest=$fileপরিবর্তে একই প্রভাব অর্জন করতে পারে। কোন বিভ্রান্তির জন্য দুঃখিত।

গুরুত্বপূর্ণ বিষয়টি লক্ষণীয় হ'ল আপনি একেবারে, কোনও পরিস্থিতিতেই মানবজাতির কোনও অবস্থাতেই, ls এর আউটপুটটিকে বিশ্লেষণ করবেন না। না।


নোট করুন যে lsভিত্তিক ভিত্তিক পদ্ধতির বিপরীতে , যদি সিমলিংক থাকে, তবে সিমলিংকের লক্ষ্য পরিবর্তনের সময় বিবেচনা করা হবে ( সেখানে একই আচরণের জন্য -Lবিকল্প যুক্ত করুন ls)।
স্টাফেন চেজেলাস

0

আমি মনে করি যে এখানে সর্বোত্তম বিকল্পটি হ'ল:

ls -rf $MY_DIR/FILE.*.xml
if [ $? -eq 0 ]; then
      INPUT_FILE=`ls -rt $MY_DIR/FILE.*.xml|head -1|xargs basename `
else
      echo "Error!"
fi

যদি কোনও ফাইল না থাকে তবে ls এর রিটার্ন কোড 2 হয় তবে এটি যদি খুঁজে পায় তবে কোনও ফাইল 0 হবে।


2
তুলনা করার পরিবর্তে $?বিরুদ্ধে 0, আপনি এটা করতে পারেন: if ls -rf $MY_DIR/FILE.*.xml ; then

এছাড়াও, আপনি প্রথম কমন্ডের আউটপুটটিকে পুনর্নির্দেশ করতে পারেন /dev/nullls -rf $MY_DIR/FILE.*.xml &> /dev/null। এইভাবে, ব্যবহারকারী অতিরিক্ত আউটপুট দেখতে পাবেন না।
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.