পসিক্স কমপ্লায়েন্ট উপায় হ'ল স্পেসের সাথে ফাইলের নামের সাথে কাজ করার উপায়


14

আমি বাশ স্ক্রিপ্টিং গাইডকে হোয়াইটস্পেসযুক্ত ফাইলের সাথে কাজ করার জন্য অ্যারের ব্যবহারের পরামর্শ দিচ্ছি। ড্যাশএএসবিন্স তবে পরামর্শ দেয় যে অ্যারেগুলি পোর্টেবল নয় তাই আমি হোয়াইটস্পেস থাকতে পারে এমন ফাইলের নামের সাথে কাজ করার একটি পসিক্স অনুগত উপায়ের সন্ধান করছি।

আমি নীচের উদাহরণে স্ক্রিপ্টটি পরিবর্তন করতে দেখছি যাতে এটি হয় would echo

foo/target/a.jar
foo/target/b.jar
bar/target/lol whitespace.jar

এখানে স্ক্রিপ্ট

#!/usr/bin/env sh

INPUT="foo/target/a.jar
foo/target/b.jar
bar/target/b.jar
bar/target/lol whitespace.jar"
# this would be produced by a 'ls' command
# We can execute the ls within the script, if it helps

dostuffwith() { echo $1; };

F_LOCATIONS=$INPUT
ALL_FILES=$(for f in $F_LOCATIONS; do echo `basename $f`; done)
ALL_FILES=$(echo "$ALL_FILES" | sort | uniq)

for f in $ALL_FILES
do
    fpath=$(echo "$F_LOCATIONS" | grep -m1 $f)
    dostuffwith $fpath
done

উত্তর:


8

POSIX শাঁস এক অ্যারে আছে: অবস্থানগত মাপদণ্ডগুলি ( $1, $2ইত্যাদি সম্মিলিতভাবে হিসাবে উল্লেখ "$@")।

set -- 'foo/target/a.jar' 'foo/target/b.jar' 'bar/target/b.jar' 'bar/target/lol whitespace.jar'
set -- "$@" '/another/one at the end.jar'

for jar do
  dostuffwith "$jar"
done

এটি অসুবিধাজনক কারণ এখানে কেবল একটি রয়েছে এবং এটি অবস্থানগত পরামিতিগুলির অন্য কোনও ব্যবহারকে ধ্বংস করে। অবস্থানগত পরামিতিগুলি কোনও ফাংশনের স্থানীয়, যা কখনও কখনও আশীর্বাদ এবং কখনও কখনও অভিশাপ হয়।

যদি আপনার ফাইলের নামগুলি নতুন লাইন না রাখার গ্যারান্টিযুক্ত থাকে তবে আপনি বিভাজক হিসাবে নিউলাইনগুলি ব্যবহার করতে পারেন। আপনি যখন ভেরিয়েবলটি প্রসারিত করবেন, প্রথমে গ্লোববিং বন্ধ করুন set -fএবং IFSকেবলমাত্র একটি নতুন লাইন অন্তর্ভুক্ত করতে ফিল্ড বিভাজন অক্ষরের তালিকা সেট করুন ।

INPUT="foo/target/a.jar
foo/target/b.jar
bar/target/b.jar
bar/target/lol whitespace.jar"

set -f; IFS='
'                           # turn off variable value expansion except for splitting at newlines
for jar in $INPUT; do
  set +f; unset IFS
  dostuffwith "$jar"        # restore globbing and field splitting at all whitespace
done
set +f; unset IFS           # do it again in case $INPUT was empty

আপনার তালিকার আইটেমগুলি নিউলাইন দ্বারা পৃথক করে, আপনি বিশেষ করে বিশেষত অনেকগুলি পাঠ্য প্রক্রিয়াকরণ আদেশ ব্যবহার করতে পারেন sort

ভেরিয়েবল বিকল্পগুলির চারপাশে সর্বদা ডাবল কোট রাখার কথা মনে রাখবেন, আপনি যখন স্পষ্টভাবে ফিল্ড বিভাজন ঘটতে চান (ততক্ষণ আপনি গ্লোব্বিং, যদি আপনি এটি বন্ধ না করেন)।


ভাল উত্তর এবং ব্যাখ্যা। আমি এটি স্বীকৃত হিসাবে চিহ্নিত করতে চলেছি কারণ এটি মূল sort | uniqপদক্ষেপটি ইচ্ছাকৃত করে তোলে ।
ইয়েরো অ্যালটনেন

5

যেহেতু আপনার $INPUTপরিবর্তনশীল বিভাজক হিসাবে নিউলাইনগুলি ব্যবহার করে, তাই আমি ধরে নিচ্ছি যে আপনার ফাইলগুলির নামগুলিতে নতুন লাইন থাকবে না। যেমন, হ্যাঁ, ফাইলগুলির মাধ্যমে পুনরাবৃত্তি করার এবং সাদা স্থান সংরক্ষণের একটি সহজ উপায় রয়েছে।

ধারণাটি হ'ল readশেল বিল্টিন ব্যবহার করা । সাধারণত readযে কোনও শ্বেত স্পেসে বিভক্ত হয়ে যায় এবং তাই স্পেসগুলি এটি ভেঙে দেয়। তবে আপনি সেট করতে পারেন IFS=$'\n'এবং এটি কেবলমাত্র নতুন লাইনে বিভক্ত হবে। সুতরাং আপনি আপনার তালিকার প্রতিটি লাইনে পুনরাবৃত্তি করতে পারেন।

এখানে আমি যে ক্ষুদ্রতম সমাধানটি নিয়ে আসতে পারি তা এখানে:

INPUT="foo/target/a.jar
foo/target/b.jar
bar/target/b.jar
bar/target/lol whitespace.jar"

dostuffwith() {
    echo "$1"
}

echo "$INPUT" | awk -F/ '{if (!seen[$NF]++) print }' | \
while IFS=$'\n' read file; do
  dostuffwith "$file"
done

মূলত এটি "$ INPUT" প্রেরণ করে awkযা ফাইলের নামের উপর ভিত্তি করে প্রতিলিপিগুলি (এটি বিভাজিত হয় /এবং তারপরে শেষ আইটেমটি আগে দেখা না গেলে লাইনটি মুদ্রণ করে)। তারপরে একবার awk ফাইল পাথের তালিকা তৈরি করেছে, আমরা while readতালিকাটির মাধ্যমে পুনরাবৃত্তি করতে ব্যবহার করব ।


। চেকব্যাশিজম বার.শ বারেশ লাইন 14 এ সম্ভাব্য বাশিজম (<<< স্ট্রিং এখানে)
ইয়েরো অ্যালটনেন

1
অ্যারোস্ট্রিং ব্যবহার না করার জন্য @ ইরো অ্যালটনেন এটি পরিবর্তন করেছেন। উল্লেখ্য যে এই পরিবর্তনের সাথে সাথে whileলুপটি, এবং এভাবে dostuffwithএকটি সাবশেলে কার্যকর করা হয়। সুতরাং চলমান শেলটিতে তৈরি হওয়া কোনও পরিবর্তনশীল বা পরিবর্তনগুলি লুপটি সম্পূর্ণ হওয়ার পরে হারিয়ে যাবে। সম্পূর্ণ বিকল্পটি হ'ল একমাত্র বিকল্প হ'ল এটি যে অপ্রীতিকর নয়, তবে আমি ভেবেছিলাম এটি ভাল this
প্যাট্রিক

আমি ক্ষুদ্রতার চেয়ে পাঠযোগ্যতার উপর ভিত্তি করে পয়েন্ট প্রদান করছি। এটি অবশ্যই কাজ করে এবং ইতিমধ্যে এটির জন্য +1।
ইয়েরো অ্যালটনেন

IFS="\n"ব্যাকস্ল্যাশ এবং এন অক্ষরগুলিতে বিভক্ত হয়। কিন্তু মধ্যে read file, কোন বিভাজন আছে। IFS="\n"এটি এখনও কার্যকর যে এটি $ আইএফএস থেকে ফাঁকা অক্ষরগুলি সরিয়ে দেয় যা অন্যথায় ইনপুটটির শুরু এবং শেষে ছিনিয়ে নেওয়া হত। একটি লাইন পড়ার জন্য IFS= read -r line, প্রামাণ্য বাক্য গঠনটি হ'ল , যদিও IFS=anything read -r line(প্রদত্ত যে কোনও কিছুই শূন্যস্থান না রাখে) পাশাপাশি কাজ করবে।
স্টাফেন চেজেলাস

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