বাশে কোনও পাঠ্য ফাইল থেকে একটি অ্যারে তৈরি করা হচ্ছে


88

একটি স্ক্রিপ্ট একটি URL লাগে, প্রয়োজনীয় ক্ষেত্রগুলি জন্য এটি parses এবং পুননির্দেশনা তার আউটপুট একটি ফাইলে সংরক্ষণ করা হবে, file.txt যাও । প্রতিবার ক্ষেত্রটি সন্ধান করার পরে আউটপুট একটি নতুন লাইনে সংরক্ষণ করা হয়।

file.txt

A Cat
A Dog
A Mouse 
etc... 

আমি file.txtএটি থেকে একটি নতুন স্ক্রিপ্টে একটি অ্যারে নিতে এবং তৈরি করতে চাই , যেখানে প্রতিটি লাইন অ্যারেতে তার নিজস্ব স্ট্রিং ভেরিয়েবল হতে পারে। এখন পর্যন্ত আমি চেষ্টা করেছি:

#!/bin/bash

filename=file.txt
declare -a myArray
myArray=(`cat "$filename"`)

for (( i = 0 ; i < 9 ; i++))
do
  echo "Element [$i]: ${myArray[$i]}"
done

আমি যখন এই স্ক্রিপ্টটি চালনা করি তখন শ্বেত স্পেসের ফলে শব্দগুলি বিভক্ত হয়ে যায় এবং পরিবর্তে পরিবর্তিত হয়

পছন্দসই আউটপুট

Element [0]: A Cat 
Element [1]: A Dog 
etc... 

আমি এটি পেয়ে শেষ:

আসল আউটপুট

Element [0]: A 
Element [1]: Cat 
Element [2]: A
Element [3]: Dog 
etc... 

আমি কীভাবে নীচের লুপটি সামঞ্জস্য করতে পারি যে প্রতিটি লাইনের পুরো স্ট্রিং অ্যারেতে প্রতিটি ভেরিয়েবলের সাথে একের সাথে মিলিত হয়?


4
এটিই বাশ এফএকিউ 001 সম্পর্কিত । এছাড়াও বাশ FAQ 005 এ অ্যারের বিষয়ের এই বিভাগ
এটান রিজনার

4
আমি এটিকে স্ট্যাকওভারফ্লো ডাব্লিকেট হিসাবে জিজ্ঞাসা করব / প্রশ্নগুলি 1111383817/… , তবে সেখানে গৃহীত উত্তরটি ভয়াবহ।
চার্লস ডাফি

এটান, এত দ্রুত এবং নির্ভুল উত্তরের জন্য আপনাকে অনেক ধন্যবাদ! আমি ফোরামগুলিতে আমার প্রশ্নটি অনুসন্ধান করার চেষ্টা করেছি, তবে স্ট্যাকওভারফ্লো সম্পর্কে FAQ অনুসন্ধান করার জন্য ভাবি নি। ম্যাপফিল কমান্ডটি আমার প্রয়োজনগুলি ঠিকভাবে সম্বোধন করেছে! আবারও ধন্যবাদ :) বিভাগে উত্তর 2.1
ব্যবহারকারী2856414

4
(লিঙ্কটি বিপরীত দিকে সেট আপ করুন, যেহেতু আমাদের কাছে আমাদের চেয়ে এখানে আরও ভাল গ্রহণযোগ্য উত্তর রয়েছে)।
চার্লস ডাফি

উত্তর:


110

mapfileকমান্ডটি ব্যবহার করুন :

mapfile -t myArray < file.txt

ত্রুটিটি ব্যবহার করা হচ্ছে for- কোনও ফাইলের লাইনে লুপ নেওয়ার idiomatic উপায়টি হ'ল:

while IFS= read -r line; do echo ">>$line<<"; done < file.txt

দেখুন BashFAQ / ২005 আরো বিস্তারিত জানার জন্য।


4
যেহেতু এই ক্যানোনিকাল Q & A- যেমন উন্নীত করা হচ্ছে, আপনার কাছে অন্তর্ভুক্ত হতে পারে কি লিংক উল্লেখ করা হয়: while IFS= read -r; do lines+=("$REPLY"); done <file
ফেডরকিই 'এসও ক্ষতিগ্রস্থ হওয়া বন্ধ করুন'

10
মানচিত্রের ফাইলটি 4.x এর আগে বাশ সংস্করণগুলিতে বিদ্যমান নেই
এরিক্ল্যাশ

14
বাশ 4 এখন প্রায় 5 বছর বয়সী। আপগ্রেড।
গ্লেন জ্যাকম্যান 31'17

4
২০০৯-এ বাশ ৪ মুক্তি পাওয়ার পরেও @ এরিকস্লোর মন্তব্য প্রাসঙ্গিক রয়েছে কারণ অনেক মেশিন এখনও ব্যাশ ৩.x দিয়ে প্রেরণ করে (এবং আপগ্রেড হবে না, যতক্ষণ না জিপিএলভি 3 এর অধীনে বাশ প্রকাশিত হবে)। আপনি যদি বহনযোগ্যতায় আগ্রহী হন, তবে এটি লক্ষণীয় একটি গুরুত্বপূর্ণ বিষয়
ডি নভো

12
সমস্যাটি এমন নয় যে কোনও বিকাশকারী একটি আপগ্রেড সংস্করণ ইনস্টল করতে পারে না, এটি কোনও বিকাশকারীকে সচেতন হওয়া উচিত যে mapfileঅতিরিক্ত কোনও পদক্ষেপ ছাড়াই অনেকগুলি মেশিনে প্রত্যাশা অনুযায়ী স্ক্রিপ্ট চলবে না। @ এরিক্লাজা ম্যাক্স প্রত্যাশিত ভবিষ্যতের জন্য 3.2.57 বাশ দিয়ে চালিয়ে যেতে থাকবে। আরও সাম্প্রতিক সংস্করণগুলিতে এমন কোনও লাইসেন্স ব্যবহার করা হয় যা সেগুলি ভাগ করতে বা মঞ্জুরি দিতে চান না এমন জিনিসগুলি ভাগ করতে বা মঞ্জুরি দেওয়ার জন্য অ্যাপলের প্রয়োজন।
দে নভো

24

mapfileএবং readarray(যা সমার্থক শব্দ) বাশ সংস্করণ 4 এবং এর উপরেরগুলিতে উপলব্ধ। আপনার যদি বাশের একটি পুরানো সংস্করণ থাকে তবে আপনি ফাইলটি একটি অ্যারেতে পড়তে একটি লুপ ব্যবহার করতে পারেন:

arr=()
while IFS= read -r line; do
  arr+=("$line")
done < file

যদি ফাইলটির শেষ লাইনে একটি অসম্পূর্ণ (অনুপস্থিত নিউলাইন থাকে) আপনি এই বিকল্পটি ব্যবহার করতে পারেন:

arr=()
while IFS= read -r line || [[ "$line" ]]; do
  arr+=("$line")
done < file

সম্পর্কিত:


আমি এটি দেখতে পাচ্ছি যে IFS= read -r line || [[ "$line" ]]এটির কাজ করার জন্য আমাকে প্রথম বন্ধনী স্থাপন করতে হবে । অন্যথায়, এটি দুর্দান্ত কাজ করে!
তাতিয়ানা রাচেভা

@ টাটিয়ানাচেচেভা: সেমিকোলনটি যা আগে অনুপস্থিত ছিল তা নয় do?
কোডফোরস্টার

9

তুমিও এটা করতে পার:

oldIFS="$IFS"
IFS=$'\n' arr=($(<file))
IFS="$oldIFS"
echo "${arr[1]}" # It will print `A Dog`.

বিঃদ্রঃ:

ফাইলের নাম সম্প্রসারণ এখনও ঘটে। উদাহরণস্বরূপ, যদি আক্ষরিক একটি রেখা থাকে তবে *এটি বর্তমান ফোল্ডারের সমস্ত ফাইলে প্রসারিত হবে। সুতরাং কেবলমাত্র এটি ব্যবহার করুন যদি আপনার ফাইলটি এই ধরণের পরিস্থিতি থেকে মুক্ত থাকে।


IFSঅ্যাসাইনমেন্টটি অবিরত রেখে arrকি কেবল অস্থায়ীভাবে সেট করার কোনও উপায় আছে (যাতে এটি এই আদেশের পরে এটির মূল মূল্যটি পুনরুদ্ধার করে) ?
হিউজ

4
নোট করুন যে ফাইলের নাম সম্প্রসারণ এখনও ঘটে; উদাহরণস্বরূপIFS=$'\n' arr=($(echo 'a 1'; echo '*'; echo 'b 2')); printf "%s\n" "${arr[@]}"
হিউজ

@ হিউগস: হ্যাঁ, ফাইলের নাম সম্প্রসারণ এখনও ঘটে। আমি সেই বিট তথ্যটি যুক্ত করব..তাহিনী ..
জাহিদ

দুঃখিত, আমি একমত নই বর্তমান শেল IFS=... commandপরিবর্তন হয় না IFS। যাইহোক, IFS=... other_variable=...(কোনও কমান্ড ব্যতীত) IFSএবং other_variableবর্তমান শেল উভয়ই পরিবর্তন করে ।
হিউজ

4
ধন্যবাদ! এইটা কাজ করে; এটি দুর্ভাগ্যজনক যে আমি arr=নোটেশনটি পছন্দ করার মতো কোনও সহজ উপায় নেই ( mapfile/ এর তুলনায় readarray)।
হিউজ

4

আপনি কেবল ফাইলটি থেকে প্রতিটি লাইন পড়তে পারেন এবং এটি একটি অ্যারেতে নির্ধারণ করতে পারেন।

#!/bin/bash
i=0
while read line 
do
        arr[$i]="$line"
        i=$((i+1))
done < file.txt

4
আপনি অ্যারে অ্যাক্সেস করবেন কীভাবে?
হোলা

4

ম্যাপফল বা পড়ুন -a ব্যবহার করুন

সর্বদা শেলচেক ব্যবহার করে আপনার কোড পরীক্ষা করুন । এটি প্রায়শই আপনাকে সঠিক উত্তর দেয়। এই ক্ষেত্রে এসসি 2207 এমন একটি ফাইল পড়া কভার করে যা ফাঁকে পৃথক করা হয়েছে বা নিউরেইন দ্বারা পৃথক করা মানগুলি একটি অ্যারেতে রয়েছে।

এটি করবেন না

array=( $(mycommand) )

নিউলাইনগুলি দ্বারা পৃথক করা মান সহ ফাইলগুলি

mapfile -t array < <(mycommand)

স্পেস দ্বারা পৃথক মান সহ ফাইলগুলি

IFS=" " read -r -a array <<< "$(mycommand)"

শেলচেক পৃষ্ঠাটি আপনাকে এটিকে সর্বোত্তম অনুশীলন হিসাবে বিবেচনা করার কারণটি সরবরাহ করবে।


0

এই উত্তরটি ব্যবহার করতে বলে

mapfile -t myArray < file.txt

আমি একটি তৈরি shim জন্য mapfileআপনি ব্যবহার করতে চান তাহলে mapfileব্যাশ <কারনের জন্য 4.x উপর। mapfileআপনি বশ> = 4.x এ থাকলে এটি বিদ্যমান কমান্ডটি ব্যবহার করে

বর্তমানে, কেবলমাত্র বিকল্প -dএবং -tকাজ। তবে উপরের এই কমান্ডের জন্য এটি যথেষ্ট হওয়া উচিত। আমি কেবল ম্যাকোজে পরীক্ষা করেছি। ম্যাকোস সিয়েরা 10.12.6 এ, সিস্টেম ব্যাশ 3.2.57(1)-release। তাই শিম কাজে আসতে পারে। আপনি কেবল হোমব্রিউ দিয়ে আপনার ব্যাশ আপডেট করতে পারেন, নিজেই ব্যাশ তৈরি করতে পারেন, ইত্যাদি can

এটি একটি কল স্ট্যাক ভেরিয়েবল সেট আপ করতে এই কৌশলটি ব্যবহার করে ।

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