বাশের কোনও ফাইলের সামগ্রীর মধ্য দিয়ে লুপিং


1387

আমি কীভাবে বাশের সাহায্যে পাঠ্য ফাইলের প্রতিটি লাইনটি পুনরায় পাঠ করব ?

এই স্ক্রিপ্ট সহ:

echo "Start!"
for p in (peptides.txt)
do
    echo "${p}"
done

আমি স্ক্রিনে এই আউটপুট পেতে:

Start!
./runPep.sh: line 3: syntax error near unexpected token `('
./runPep.sh: line 3: `for p in (peptides.txt)'

(পরে আমি $pকেবল পর্দায় আউটপুট না দিয়ে আরও জটিল কিছু করতে চাই ))


পরিবেশের পরিবর্তনশীল শেলটি হ'ল (এনভির থেকে):

SHELL=/bin/bash

/bin/bash --version আউটপুট:

GNU bash, version 3.1.17(1)-release (x86_64-suse-linux-gnu)
Copyright (C) 2005 Free Software Foundation, Inc.

cat /proc/version আউটপুট:

Linux version 2.6.18.2-34-default (geeko@buildhost) (gcc version 4.1.2 20061115 (prerelease) (SUSE Linux)) #1 SMP Mon Nov 27 11:46:27 UTC 2006

পেপটাইডস.টিএসটি ফাইলের মধ্যে রয়েছে:

RKEKNVQ
IPKKLLQK
QYFHQLEKMNVK
IPKKLLQK
GDLSTALEVAIDCYEK
QYFHQLEKMNVKIPENIYR
RKEKNVQ
VLAKHGKLQDAIN
ILGFMK
LEDVALQILL

19
ওহ, আমি এখানে অনেক কিছু ঘটেছে দেখেছি: সমস্ত মন্তব্য মুছে ফেলা হয়েছে এবং প্রশ্নটি আবার খোলা হচ্ছে। কেবলমাত্র রেফারেন্সের জন্য, গ্রহণযোগ্য উত্তরটি একটি ফাইল লাইনে একটি লাইনের সাথে একটি ভেরিয়েবলের মান নির্ধারণ করে একটি সাধারণভাবে সমস্যাটিকে সম্বোধন করে এবং এখানে গ্রহণযোগ্যটির চেয়ে পছন্দ করা উচিত।
ফেডরকিই 'এসও ক্ষতিগ্রস্থ হওয়া বন্ধ করুন'

উত্তর:


2088

এটি করার একটি উপায়:

while read p; do
  echo "$p"
done <peptides.txt

মন্তব্যে নির্দেশিত হিসাবে, এর নেতৃস্থানীয় হোয়াইটস্পেস ট্রিমিং, ব্যাকস্ল্যাশ সিকোয়েন্সগুলি ব্যাখ্যা করা এবং শেষ পংক্তিটি যদি কোনও সমাপ্ত লাইনফিড অনুপস্থিত থাকে তবে শেষ লাইনটি এড়িয়ে যাওয়ার পার্শ্ব প্রতিক্রিয়া রয়েছে। এগুলি যদি উদ্বেগজনক হয় তবে আপনি এটি করতে পারেন:

while IFS="" read -r p || [ -n "$p" ]
do
  printf '%s\n' "$p"
done < peptides.txt

ব্যতিক্রমীভাবে, যদি লুপের বডি স্ট্যান্ডার্ড ইনপুট থেকে পড়তে পারে তবে আপনি আলাদা ফাইল বর্ণনাকারী ব্যবহার করে ফাইলটি খুলতে পারেন:

while read -u 10 p; do
  ...
done 10<peptides.txt

এখানে 10 টি কেবল একটি স্বেচ্ছাসেবী সংখ্যা (0, 1, 2 থেকে পৃথক)।


7
আমি কিভাবে শেষ পংক্তির ব্যাখ্যা করব? ফাইল পেপটাইডস.টিএসটিএসটি স্ট্যান্ডার্ড ইনপুটটিতে পুনঃনির্দেশিত হয় এবং কোনওভাবে পুরো ব্লক করার পরে?
পিটার মর্টেনসেন

11
"লুপ চলাকালীন এতে স্লুর্প পেপটাইডস টেক্সট করুন, সুতরাং 'পঠন' কমান্ডের কিছু গ্রাস করার আছে। আমার "বিড়াল" পদ্ধতিটি অনুরূপ, কমান্ডের আউটপুটটিকে 'রিড' দ্বারা গ্রাহনের জন্য যখন ব্লকটিতে প্রেরণ করে, কেবল এটি কাজটি সম্পাদন করার জন্য অন্য প্রোগ্রাম শুরু করে।
ওয়ারেন ইয়ং

8
এই পদ্ধতিটি কোনও ফাইলের শেষ লাইনটি এড়িয়ে চলেছে বলে মনে হচ্ছে।
xastor

5
ডাবল রেখায় লাইন !! প্রতিধ্বনি "$ পি" এবং ফাইল .. বিশ্বাস করুন এটি আপনি কামড়ান যদি আপনি না !!! আমি জানি! লল
মাইকে কিউ

5
উভয় সংস্করণ একটি চূড়ান্ত লাইনটি পড়তে ব্যর্থ হয় যদি এটি কোনও নতুন লাইনের সাথে শেষ হয় না। সর্বদা ব্যবহারwhile read p || [[ -n $p ]]; do ...
Dawg

446
cat peptides.txt | while read line 
do
   # do something with $line here
done

এবং ওয়ান-লাইনার বৈকল্পিক:

cat peptides.txt | while read line; do something_with_$line_here; done

কোনও বিকল্প লাইনের ফিড না থাকলে এই বিকল্পগুলি ফাইলের শেষ লাইনটি এড়িয়ে যাবে।

আপনি নিম্নলিখিত দ্বারা এড়াতে পারেন:

cat peptides.txt | while read line || [[ -n $line ]];
do
   # do something with $line here
done

68
সাধারণভাবে, আপনি যদি কেবলমাত্র একটি যুক্তি দিয়ে "বিড়াল" ব্যবহার করেন, আপনি কিছু ভুল করছেন (বা সাবপটিমাল)।
জেস্পের ই

27
হ্যাঁ, এটি ব্রুনোর মতো দক্ষ নয়, কারণ এটি অযথা অন্য প্রোগ্রাম শুরু করে। দক্ষতা যদি গুরুত্বপূর্ণ হয় তবে এটি ব্রুনোর উপায়ে করুন। আমার উপায়টি মনে আছে কারণ আপনি অন্যান্য কমান্ডের সাহায্যে এটি ব্যবহার করতে পারেন, যেখানে "সিন্ট্যাক্স থেকে" পুনর্নির্দেশ "কাজ করে না।
ওয়ারেন ইয়ং

74
এর সাথে আরও একটি গুরুতর সমস্যা রয়েছে: কারণ লুপটি পাইপলাইনের একটি অংশ, এটি একটি সাবশেলে চালিত হয় এবং অতএব লুপের অভ্যন্তরে অবস্থিত যে কোনও ভেরিয়েবলগুলি প্রস্থান করার পরে হারিয়ে যায় (দেখুন বাশ-hackers.org/wiki/doku। পিএইচপি / মিররিং / বাশফাক / 024 )। এটি খুব বিরক্তিকর হতে পারে (আপনি লুপটিতে কী করার চেষ্টা করছেন তার উপর নির্ভর করে)।
গর্ডন ডেভিসন

25
আমি প্রচুর কমান্ডের শুদ্ধভাবে আমার কমান্ডের শুরু হিসাবে "বিড়াল ফাইল |" ব্যবহার করি কারণ আমি প্রায়শই "হেড ফাইল |"
মাদুর কেলসি

62
এটি এতটা দক্ষ নাও হতে পারে তবে এটি অন্যান্য উত্তরের চেয়ে অনেক বেশি পঠনযোগ্য।
শেভেজ পাঠক

144

বিকল্প 1 এ: লুপ করার সময়: একক সময়ে একক লাইন: ইনপুট পুনঃনির্দেশ

#!/bin/bash
filename='peptides.txt'
echo Start
while read p; do 
    echo $p
done < $filename

বিকল্প 1 বি: লুপ করার সময়: একবারে একক লাইন:
ফাইলটি খুলুন, একটি ফাইল বর্ণনাকারী থেকে পড়ুন (এই ক্ষেত্রে ফাইল বিবরণকারী # 4)।

#!/bin/bash
filename='peptides.txt'
exec 4<$filename
echo Start
while read -u4 p ; do
    echo $p
done

বিকল্প 1 বি জন্য: ফাইল বিবরণকারী আবার বন্ধ করা প্রয়োজন? যেমন লুপটি একটি অভ্যন্তরীণ লুপ হতে পারে।
পিটার মর্টেনসেন

3
প্রক্রিয়াটি প্রস্থান করার সাথে সাথে ফাইল বর্ণনাকারী পরিষ্কার হয়ে যাবে। এফডি নম্বরটি পুনঃব্যবহার করার জন্য একটি সুস্পষ্ট কাছাকাছি কাজ করা যেতে পারে। একটি এফডি বন্ধ করতে, & এর সিনট্যাক্সের সাথে আরও একটি এক্সিকিউট ব্যবহার করুন: এক্সিকিউটিভ 4 <& -
স্টান গ্রাভস

1
অপশন 2 এর জন্য আপনাকে ধন্যবাদ। আমি বিকল্প 1 এর সাথে বিশাল সমস্যায় পড়েছি কারণ আমাকে লুপের মধ্যে স্টিডিনের কাছ থেকে পড়া দরকার; এই ক্ষেত্রে বিকল্প 1 কাজ করবে না।
মাসগো

4
আপনার আরও পরিষ্কারভাবে উল্লেখ করা উচিত যে বিকল্প 2 দৃ strongly়ভাবে নিরুৎসাহিত । @masgo অপশন 1B যে ক্ষেত্রে কাজ করা উচিত, এবং প্রতিস্থাপন অপশন 1A থেকে ইনপুট ফেরৎ সিনট্যাক্স সঙ্গে মিলিত হতে পারে done < $filenameসঙ্গে done 4<$filename(যা আপনি একটি কমান্ড পরামিতি থেকে ফাইল নাম পড়তে চান দরকারী, যে ক্ষেত্রে আপনি শুধু প্রতিস্থাপন করতে পারেন $filenameদ্বারা $1)।
ডিম হ্যান্স

লুপের tail -n +2 myfile.txt | grep 'somepattern' | cut -f3ভিতরে ssh কমান্ড চালানোর সময় (স্টিডিন গ্রাস করে) যেমন আমার ফাইল সামগ্রীর উপর লুপ করা দরকার ; বিকল্প 2 এখানে একমাত্র উপায় বলে মনে হচ্ছে?
ব্যবহারকারী5359531

85

এটি অন্যান্য উত্তরের চেয়ে ভাল নয়, তবে ফাঁকা জায়গা ছাড়াই কোনও ফাইলের কাজ করা (মন্তব্য দেখুন) এর আরও একটি উপায়। আমি দেখতে পাই যে আমার প্রায়শই পৃথক স্ক্রিপ্ট ফাইলগুলি ব্যবহারের অতিরিক্ত ধাপ ছাড়াই পাঠ্য ফাইলগুলির তালিকাগুলির মাধ্যমে খনন করতে এক-লাইনার প্রয়োজন।

for word in $(cat peptides.txt); do echo $word; done

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

for word in $(cat peptides.txt); do cmd_a.sh $word; cmd_b.py $word; done

অথবা আপনি যদি স্ট্রিম এডিটর (শেড শিখুন) এর মতো এটি ব্যবহার করতে চান তবে নীচে অন্য আউটপুটটিকে আউটপুট ডাম্প করতে পারেন।

for word in $(cat peptides.txt); do cmd_a.sh $word; cmd_b.py $word; done > outfile.txt

আমি এগুলি উপরে লেখা হিসাবে ব্যবহার করেছি কারণ আমি পাঠ্য ফাইলগুলি ব্যবহার করেছি যেখানে আমি প্রতি লাইনে একটি শব্দ দিয়ে তাদের তৈরি করেছি। (মন্তব্য দেখুন) আপনার যদি এমন শূণ্যস্থান থাকে যা আপনি নিজের শব্দ / লাইনগুলি বিভক্ত করতে চান না তবে এটি কিছুটা কুরুচিপূর্ণ হয় তবে একই কমান্ডটি এখনও নিম্নলিখিত হিসাবে কাজ করে:

OLDIFS=$IFS; IFS=$'\n'; for line in $(cat peptides.txt); do cmd_a.sh $line; cmd_b.py $line; done > outfile.txt; IFS=$OLDIFS

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

শুভকামনা করছি!


6
বাশ $ (<পেপটাইডস.টিএসটিএসটি) সম্ভবত আরও মার্জিত, তবে এটি এখনও ভুল, জোয়াও যা সঠিক বলেছে, আপনি সেখানে কমান্ড প্রতিস্থাপন যুক্তি সম্পাদন করছেন যেখানে স্থান বা নিউলাইন একই জিনিস। যদি কোনও লাইনের মধ্যে একটি স্থান থাকে তবে লুপটি সেই এক লাইনের জন্য TWICE বা আরও কিছু চালায়। সুতরাং আপনার কোডটি যথাযথভাবে পড়া উচিত: <(<পেপটাইডেস.টিএসটি) এর শব্দের জন্য; কর .... যদি কোনও সত্যের জন্য জানতে থাকে যে কোনও স্থান নেই, তবে একটি লাইন একটি শব্দের সমান এবং আপনি ঠিক আছেন।
ম্যাক্সপলক

2
@ জোওকোস্টা, ম্যাক্সপলক: ভাল পয়েন্টগুলি যা আমি বিবেচনা করি নি। আমি তাদের প্রতিফলিত করতে মূল পোস্ট সম্পাদনা করেছি। ধন্যবাদ!
টাইপ করা যেতে পারে yp

2
ব্যবহার forইনপুট টোকেন / লাইন শেল বিস্তারের সাপেক্ষে তৈরি করে, যা সাধারণত অবাঞ্ছিত হয়; এটি ব্যবহার করে দেখুন: for l in $(echo '* b c'); do echo "[$l]"; done- যেমন আপনি দেখতে পাবেন *- যদিও মূলত একটি উদ্ধৃত আক্ষরিক - বর্তমান ডিরেক্টরিতে থাকা ফাইলগুলিতে প্রসারিত।
mklement0

2
@dblanchard: example আইএফএস ব্যবহার করে সর্বশেষ উদাহরণটি ফাঁকা স্থান উপেক্ষা করা উচিত। আপনি কি সেই সংস্করণটি ব্যবহার করে দেখেছেন?
21

4
কীভাবে এই কমান্ডটি জটিল সমস্যাগুলি স্থির হওয়ার সাথে সাথে আরও জটিল হয়, খুব ভালভাবে উপস্থাপন করে forযে ফাইল লাইনগুলি পুনরুক্ত করার জন্য কেন এটি খারাপ ধারণা। এছাড়াও, @ এমকিলেটমেন্ট ০ দ্বারা উল্লিখিত সম্প্রসারণ দিকটি (যদিও এটি সম্ভবত পলায়নযোগ্য উদ্ধৃতিগুলি এনেছে, যা আবার জিনিসগুলিকে আরও জটিল এবং কম পাঠযোগ্য করে তোলে) circum
ডিম হ্যানস

69

অন্যান্য উত্তরগুলির দ্বারা কভার করা হয়নি আরও কয়েকটি জিনিস:

একটি সীমিত ফাইল থেকে পড়া

# ':' is the delimiter here, and there are three fields on each line in the file
# IFS set below is restricted to the context of `read`, it doesn't affect any other code
while IFS=: read -r field1 field2 field3; do
  # process the fields
  # if the line has less than three fields, the missing fields will be set to an empty string
  # if the line has more than three fields, `field3` will get all the values, including the third field plus the delimiter(s)
done < input.txt

প্রক্রিয়া প্রতিস্থাপন ব্যবহার করে অন্য কমান্ডের আউটপুট থেকে পড়া

while read -r line; do
  # process the line
done < <(command ...)

এই পদ্ধতির চেয়ে ভাল command ... | while read -r line; do ...কারণ এখানে যখন লুপটি বর্তমানের শেলের পরিবর্তে পরবর্তীকালের মতো সাবসেলের চেয়ে চলমান। সম্পর্কিত পোস্টটি দেখুন কিছুক্ষণের মধ্যে পরিবর্তিত একটি পরিবর্তনশীল লুপটির স্মরণ হয় না

উদাহরণস্বরূপ একটি নাল সীমাবদ্ধ ইনপুট থেকে পড়া find ... -print0

while read -r -d '' line; do
  # logic
  # use a second 'read ... <<< "$line"' if we need to tokenize the line
done < <(find /path/to/dir -print0)

সম্পর্কিত পড়ুন: বাশাএফএকিউ / 020 - আমি কীভাবে নতুন লাইনেস, স্পেস বা উভয় সমন্বিত ফাইলের নামগুলি নিরাপদে সন্ধান করতে এবং পরিচালনা করতে পারি?

একসাথে একাধিক ফাইল থেকে পড়া

while read -u 3 -r line1 && read -u 4 -r line2; do
  # process the lines
  # note that the loop will end when we reach EOF on either of the files, because of the `&&`
done 3< input1.txt 4< input2.txt

@ চিপনারের উত্তরের ভিত্তিতে এখানে :

-uবাশ এক্সটেনশন। পসিক্স সামঞ্জস্যের জন্য, প্রতিটি কলকে দেখতে কিছুটা দেখতে পাওয়া যায় read -r X <&3

একটি অ্যারেতে পুরো ফাইলটি পড়ছি (বাশ সংস্করণগুলি 4 এর আগে)

while read -r line; do
    my_array+=("$line")
done < my_file

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

while read -r line || [[ $line ]]; do
    my_array+=("$line")
done < my_file

একটি অ্যারেতে পুরো ফাইলটি পড়া (বাশ সংস্করণ 4x এবং তারপরে)

readarray -t my_array < my_file

অথবা

mapfile -t my_array < my_file

এবং তারপর

for line in "${my_array[@]}"; do
  # process the lines
done

সম্পর্কিত পোস্ট:


নোট করুন যে আপনি পরিবর্তে command < input_filename.txtসর্বদা করতে পারেন input_generating_command | commandবাcommand < <(input_generating_command)
মাস্টারেক্সিলো

1
অ্যারে ফাইল পড়ার জন্য ধন্যবাদ। ঠিক আমার যা প্রয়োজন, কারণ আমার প্রতিটি লাইন দু'বার পার্স করতে, নতুন ভেরিয়েবল যুক্ত করতে, কিছু বৈধকরণ ইত্যাদি করতে হবে
frank_108

45

কিছুক্ষণ লুপ ব্যবহার করুন:

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

মন্তব্য:

  1. আপনি যদি IFSসঠিকভাবে সেট না করেন তবে আপনি ইনডেন্টেশন হারাবেন।

  2. আপনার প্রায়শই পড়ার সাথে -r বিকল্পটি ব্যবহার করা উচিত।

  3. সঙ্গে লাইন পড়বেন না for


2
-rবিকল্প কেন ?
ডেভিড সি র্যাঙ্কিন

2
@ ডেভিডসি.র্যাঙ্কিন--আর বিকল্পটি ব্যাকস্ল্যাশ ব্যাখ্যাকে বাধা দেয়। Note #2এটি একটি লিঙ্ক যেখানে এটি বিশদভাবে বর্ণিত হয়েছে ...
জাহিদ

এটি অন্য উত্তরে "রিড-ইউ" বিকল্পের সাথে একত্রিত করুন এবং তারপরে এটি নিখুঁত।
ফ্লোরিন আন্দ্রেই

@ ফ্লোরিনআন্দ্রেই: উপরের উদাহরণটির -uবিকল্পের প্রয়োজন নেই , আপনি কি অন্য উদাহরণের সাথে কথা বলছেন -u?
জাহিদ

আপনার লিঙ্কগুলি দেখেছেন, এবং অবাক হয়েছিলেন যে কোনও উত্তর নেই যা কেবলমাত্র আপনার লিঙ্কটি নোট 2 এ লিঙ্ক করে That এই পৃষ্ঠাটি আপনাকে সেই বিষয় সম্পর্কে জানার জন্য প্রয়োজনীয় সবকিছু সরবরাহ করে। অথবা লিংক-কেবল উত্তরগুলি নিরুৎসাহিত করা হয় বা কিছু?
ডিম হ্যান্স

14

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

$ cat /tmp/test.txt
Line 1
    Line 2 has leading space
Line 3 followed by blank line

Line 5 (follows a blank line) and has trailing space    
Line 6 has no ending CR

এখানে চারটি উপাদান রয়েছে যা বহু বাশ সমাধান দ্বারা পঠিত ফাইল আউটপুটটির অর্থকে পরিবর্তিত করবে:

  1. ফাঁকা লাইন 4;
  2. দুটি লাইনে ফাঁকা স্থানগুলি শীর্ষস্থানীয়;
  3. পৃথক রেখার অর্থ বজায় রাখা (অর্থাত্ প্রতিটি লাইনই একটি রেকর্ড);
  4. The লাইনটি কোনও সিআর দিয়ে শেষ করা হয়নি।

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

এখানে ফাইলগুলি পরিবর্তন করতে পারে এমন পদ্ধতিগুলি (কীসের তুলনায়) cat ফেরত ):

1) শেষ লাইনটি হারিয়ে এবং শীর্ষস্থানীয় এবং পিছনের স্থানগুলি:

$ while read -r p; do printf "%s\n" "'$p'"; done </tmp/test.txt
'Line 1'
'Line 2 has leading space'
'Line 3 followed by blank line'
''
'Line 5 (follows a blank line) and has trailing space'

(আপনি যদি এর while IFS= read -r p; do printf "%s\n" "'$p'"; done </tmp/test.txtপরিবর্তে করেন তবে আপনি নেতৃস্থানীয় এবং পিছনের স্থানগুলি সংরক্ষণ করেন তবে সিআর দিয়ে শেষ না হলে এটি শেষ লাইনটি হারাবেন)

2) প্রক্রিয়া বিকল্প ব্যবহার করে catইচ্ছার পুরো ফাইলটি এক ঝাঁকুনিতে পড়ে এবং স্বতন্ত্র লাইনের অর্থ হারাবে:

$ for p in "$(cat /tmp/test.txt)"; do printf "%s\n" "'$p'"; done
'Line 1
    Line 2 has leading space
Line 3 followed by blank line

Line 5 (follows a blank line) and has trailing space    
Line 6 has no ending CR'

(আপনি মুছে ফেলেন "থেকে $(cat /tmp/test.txt)আপনি বরং এক নি: শ্বাসে চেয়ে শব্দ ফাইল শব্দ করে পড়ুন। এছাড়াও সম্ভবত কি না দেয়ার উদ্দেশ্যে করা হচ্ছে ...)


একটি ফাইল লাইন বাই লাইন পড়ার এবং সমস্ত ব্যবধান সংরক্ষণ করার সবচেয়ে মজাদার এবং সহজতম উপায়:

$ while IFS= read -r line || [[ -n $line ]]; do printf "'%s'\n" "$line"; done </tmp/test.txt
'Line 1'
'    Line 2 has leading space'
'Line 3 followed by blank line'
''
'Line 5 (follows a blank line) and has trailing space    '
'Line 6 has no ending CR'

আপনি যদি শীর্ষস্থানীয় এবং ট্রেডিং স্পেসগুলি ছাঁটাই করতে চান তবে IFS=অংশটি সরিয়ে দিন :

$ while read -r line || [[ -n $line ]]; do printf "'%s'\n" "$line"; done </tmp/test.txt
'Line 1'
'Line 2 has leading space'
'Line 3 followed by blank line'
''
'Line 5 (follows a blank line) and has trailing space'
'Line 6 has no ending CR'

একটি সসীম ছাড়া (একটি টেক্সট ফাইল \n, যখন মোটামুটি সাধারণ, POSIX অধীনে ভাঙ্গা বিবেচনা করা হয়। আপনি trailing উপর নির্ভর করতে পারেন \nআপনি প্রয়োজন নেই || [[ -n $line ]]যেwhile লুপে ))

বেস FAQ এ আরও


13

আপনি যদি নতুন পংক্তির অক্ষর দ্বারা আপনার পড়াটি ভাঙতে না চান তবে ব্যবহার করুন -

#!/bin/bash
while IFS='' read -r line || [[ -n "$line" ]]; do
    echo "$line"
done < "$1"

তারপরে প্যারামিটার হিসাবে ফাইলের নাম সহ স্ক্রিপ্টটি চালান।


4
#!/bin/bash
#
# Change the file name from "test" to desired input file 
# (The comments in bash are prefixed with #'s)
for x in $(cat test.txt)
do
    echo $x
done

7
এই উত্তরটির জন্য জোরোপাইলের উত্তরে বর্ণিত সতর্কতাগুলির প্রয়োজন , এবং কোনও লাইনে শেল মেটাচ্যাক্টর রয়েছে (অব্যক্ত "$ x" কারণে) এটি খারাপভাবে ব্যর্থ হতে পারে।
টবি স্পাইট

7
আমি আসলে অবাক হয়েছি লোকেরা এখনও স্বাভাবিক নিয়ে আসে নি এর সাথে লাইনগুলি পড়বে না ...
Egor Hans

3

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

##Parse FPS from first video stream, drop quotes from fps variable
## streams.stream.0.codec_type="video"
## streams.stream.0.r_frame_rate="24000/1001"
## streams.stream.0.avg_frame_rate="24000/1001"
FPS=unknown
while read -r line; do
  if [[ $FPS == "unknown" ]] && [[ $line == *".codec_type=\"video\""* ]]; then
    echo ParseFPS $line
    FPS=parse
  fi
  if [[ $FPS == "parse" ]] && [[ $line == *".r_frame_rate="* ]]; then
    echo ParseFPS $line
    FPS=${line##*=}
    FPS="${FPS%\"}"
    FPS="${FPS#\"}"
  fi
done <<< "$(ffprobe -v quiet -print_format flat -show_format -show_streams -i "$input")"
if [ "$FPS" == "unknown" ] || [ "$FPS" == "parse" ]; then 
  echo ParseFPS Unknown frame rate
fi
echo Found $FPS

লুপের বাইরে চলক ঘোষণা করুন, মান নির্ধারণ করুন এবং এটি লুপের বাইরে ব্যবহারের প্রয়োজন <<< "$ (...)" সিনট্যাক্স। অ্যাপ্লিকেশনটি বর্তমান কনসোলের প্রসঙ্গে চালানো দরকার। কমান্ডের চারপাশে উদ্ধৃতিগুলি আউটপুট স্ট্রিমের নতুন লাইন রাখে।

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


3
উত্তরটি সঠিক হলেও, আমি বুঝতে পারি এটি এখানে কীভাবে শেষ হয়েছিল। অন্যান্য অনেক উত্তর দ্বারা প্রস্তাবিত হিসাবে প্রয়োজনীয় পদ্ধতিটি একই। এছাড়াও, এটি আপনার এফপিএস উদাহরণে সম্পূর্ণ নিমজ্জিত।
ডিম হ্যান্স

0

এটি বরং খুব দেরিতে আসছে, তবে এই ভেবে যে এটি কারও সাহায্য করতে পারে, আমি উত্তর যুক্ত করছি। এছাড়াও এটি সেরা উপায় নাও হতে পারে। headকমান্ডটি -nআর্গুমেন্টের সাথে ফাইলের শুরু থেকে এন লাইনগুলিtail পড়তে ব্যবহার করা যেতে পারে এবং তেমনি নীচে থেকে কমান্ডটি পড়তেও ব্যবহৃত হতে পারে। এখন, ফাইলটি থেকে নবম লাইন আনতে , আমরা এন লাইনগুলি হেড করি , পাইপযুক্ত ডেটা থেকে ডেটাটি কেবল 1 লাইনকে পাইপ করি।

   TOTAL_LINES=`wc -l $USER_FILE | cut -d " " -f1 `
   echo $TOTAL_LINES       # To validate total lines in the file

   for (( i=1 ; i <= $TOTAL_LINES; i++ ))
   do
      LINE=`head -n$i $USER_FILE | tail -n1`
      echo $LINE
   done

1
এটি করবেন না। লাইন সংখ্যা বেশি Looping এবং প্রণালী দ্বারা প্রতিটি লাইন আনার সময় sedবা head+ + tailহয় অবিশ্বাস্যভাবে অদক্ষ, এবং অবশ্যই প্রশ্ন কেন আপনি কেবল এখানে অন্যান্য সমাধানের এক ব্যবহার করবেন না begs। আপনার যদি লাইন নম্বরটি জানতে হয় তবে আপনার while read -rলুপটিতে একটি কাউন্টার যুক্ত করুন বা nl -baলুপের আগে প্রতিটি লাইনে একটি লাইন নম্বর উপসর্গ যুক্ত করতে ব্যবহার করুন।
ট্রিপলি

-1

@ পিটার: এটি আপনার পক্ষে কাজ করতে পারে-

echo "Start!";for p in $(cat ./pep); do
echo $p
done

এটি আউটপুট ফেরত দেবে-

Start!
RKEKNVQ
IPKKLLQK
QYFHQLEKMNVK
IPKKLLQK
GDLSTALEVAIDCYEK
QYFHQLEKMNVKIPENIYR
RKEKNVQ
VLAKHGKLQDAIN
ILGFMK
LEDVALQILL


3
এই উত্তরটি উপরের ভাল উত্তরের দ্বারা নির্ধারিত সমস্ত নীতিকে পরাজিত করছে!
কোডফোরস্টার

3
দয়া করে এই উত্তরটি মুছুন।
ডাব

3
এখন বলছি, বাড়াবাড়ি করবেন না। উত্তরটি খারাপ, তবে কমপক্ষে সাধারণ ব্যবহারের ক্ষেত্রে এটি কার্যকর বলে মনে হচ্ছে। যতক্ষণ না এটি সরবরাহ করা হয় ততক্ষণ একটি খারাপ উত্তর হওয়া উত্তরটির উপস্থিতির অধিকার হরণ করে না।
ডিম হ্যান্স

3
@ ইগরহানস, আমি দৃ strongly়ভাবে একমত নই: উত্তরের মূল বিষয়টি হল কিভাবে সফ্টওয়্যার লিখতে হয় তা শেখানো। লোকদের এমনভাবে কাজ করতে শেখানো যাতে আপনি জানেন যে তাদের পক্ষে ক্ষতিকারক এবং যারা তাদের সফ্টওয়্যার ব্যবহার করেন (বাগ / অপ্রত্যাশিত আচরণ / ইত্যাদি প্রবর্তন করছেন) জেনে বুঝে অন্যের ক্ষতি করছে। ক্ষতিকারক হিসাবে পরিচিত একটি উত্তরের একটি সু-সজ্জিত শিক্ষণ সংস্থার "অস্তিত্বের অধিকার" নেই (এবং এটির ব্যাখ্যাটি আমরা, ভোটদান এবং পতাকাবাহী যারা এখানে আছেন তারা অনুধাবন করছেন)।
চার্লস ডাফি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.