একটি ফাইলের লাইন উপর লুপ কিভাবে?


61

বলুন আমার কাছে এই ফাইলটি রয়েছে:

hello
world
hello world

এই প্রোগ্রাম

#!/bin/bash

for i in $(cat $1); do
    echo "tester: $i"
done

আউটপুট

tester: hello
tester: world
tester: hello
tester: world

আমি forপ্রতিটি লাইনের পুনরাবৃত্তিকে পৃথকভাবে সাদা স্পেসগুলি উপেক্ষা করে রাখতে চাই , যদিও শেষ দুটি রেখাটি প্রতিস্থাপন করা উচিত

tester: hello world

উদ্ধৃতি ব্যবহার করে for i in "$(cat $1)";ফলাফলগুলি iএকবারে পুরো ফাইলটি অর্পণ করা হবে। আমার কী পরিবর্তন হবে?

উত্তর:


69

সাথে forএবং আইএফএস :

#!/bin/bash

IFS=$'\n'       # make newlines the only separator
set -f          # disable globbing
for i in $(cat < "$1"); do
  echo "tester: $i"
done

তবে নোট করুন যে এটি আইএফএস-সাদা-স্থানের অক্ষর হিসাবে নিউলাইন হিসাবে খালি রেখাগুলি এড়িয়ে যাবে , এর ক্রমগুলি 1 হিসাবে গণনা করা হয় এবং শীর্ষস্থানীয় এবং অনুসরণকারী অগ্রাহ্য করা হয়। সঙ্গে zshএবং ksh93(না bash), আপনি এটি পরিবর্তন করতে পারেন IFS=$'\n\n'সম্পর্কে newline বিশেষভাবে চিকিত্সা করা না করার জন্য, তবে নোট করুন যে সমস্ত trailing সম্পর্কে newline অক্ষর (যাতে খালি লাইন trailing অন্তর্ভুক্ত) সবসময় কমান্ড প্রতিকল্পন দ্বারা সরানো হবে।

বা এর সাথেread (আর নেই cat):

#!/bin/bash

while IFS= read -r line; do
  echo "tester: $line"
done < "$1"

সেখানে, খালি লাইনগুলি সংরক্ষণ করা হয়েছে, তবে মনে রাখবেন যে এটি যদি নতুন লাইনের চরিত্রের দ্বারা সঠিকভাবে ডিলিট না করা হয় তবে এটি শেষ লাইনটি এড়িয়ে যাবে।


5
ধন্যবাদ, আমি জানতাম না যে কেউ <পুরো লুপটিতে প্রবেশ করতে পারে । এটা তোলে যদিও পুরোপুরি অর্থে এখন আমি দেখে
Tobias Kienzler

1
আমি দেখতে পাচ্ছি IFS \ read -r line' in second example. Is really আইএফএস = `দরকার? এটি বলার জন্য যথেষ্ট পরিমাণে আইএমএইচও করুন:while read -r line; do echo "tester: $line"; done < "$1"
গ্রেজগোর্জ ওয়েয়ারজোয়াভিস্কি

4
@ গ্রজেগোর্জউইয়ারজোইকিকি IFS=নেতৃস্থানীয় এবং পিছনের হোয়াইটস্পেসের ফেলা বন্ধ করে দিয়েছেন। ইনwhile IFS= read..
গিলস

0

এটির মূল্যের জন্য, আমি এটি প্রায়শই করা দরকার এবং ব্যবহারের সঠিক উপায়টি কখনই মনে করতে পারি না while IFS= read..., তাই আমি আমার বাশ প্রোফাইলে নিম্নলিখিত ফাংশনটি সংজ্ঞায়িত করেছি:

# iterate the line of a file and call input function
iterlines() {
    (( $# < 2 )) && { echo "Usage: iterlines <File> <Callback>"; return; }
    local File=$1
    local Func=$2
    n=$(cat "$File" | wc -l)
    for (( i=1; i<=n; i++ )); do
        "$Func" "$(sed "${i}q;d" "$File")"
    done
}

এই ফাংশনটি প্রথমে ফাইলটিতে রেখার সংখ্যা নির্ধারণ করে, তারপরে sedলাইনের পরে লাইন বের করতে ব্যবহার করে এবং প্রতিটি লাইনকে কোনও স্ট্রিং আর্গুমেন্ট হিসাবে কোনও প্রদত্ত ফাংশনে পাস করে। আমি মনে করি এটি বড় ফাইলগুলির সাথে সত্যই অকার্যকর হয়ে উঠতে পারে তবে এখন পর্যন্ত আমার পক্ষে এটি কোনও সমস্যা হয়ে ওঠেনি (অবশ্যই এই স্বাগতটির উন্নতি করার জন্য পরামর্শ)।

ব্যবহারটি বেশ মিষ্টি আইএমও:

>> cat example.txt # note the use of spaces, whitespace, etc.
a/path

This is a sentence.
"wi\th quotes"
$End
>> iterlines example.txt echo # preserves quotes, $ and whitespace
a/path

This is a sentence.
"wi\th quotes"
$End
>> x() { echo "$#"; }; iterlines example.txt x # line always passed as single input string
1
1 
1
1
1
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.