linux - বাশে একটি ফাইল কন্টেন্ট মাধ্যমে looping




bash loops (8)

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

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

এই আউটপুট ফিরে হবে-

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

কিভাবে আমি Bash সঙ্গে একটি টেক্সট ফাইল প্রতিটি লাইন মাধ্যমে পুনরাবৃত্তি করবেন?

এই স্ক্রিপ্ট সঙ্গে:

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 (env থেকে):

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 ([email protected]) (gcc version 4.1.2 20061115 (prerelease) (SUSE Linux)) #1 SMP Mon Nov 27 11:46:27 UTC 2006

ফাইল peptides.txt রয়েছে:

RKEKNVQ
IPKKLLQK
QYFHQLEKMNVK
IPKKLLQK
GDLSTALEVAIDCYEK
QYFHQLEKMNVKIPENIYR
RKEKNVQ
VLAKHGKLQDAIN
ILGFMK
LEDVALQILL

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

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

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


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

##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

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

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


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

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

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

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

এটি শুধুমাত্র শূন্যস্থানগুলিকে কেবল স্থান নয়, স্থানগুলিতে বিভক্ত করার জন্য বলে, তারপরে পরিবেশটি আবার আগের অবস্থায় ফিরিয়ে দেয়। এই মুহুর্তে, আপনি এটি সবগুলিকে একক লাইনে সঙ্কুচিত করার পরিবর্তে শেল স্ক্রিপ্টে সন্নিবেশ করাতে বিবেচনা করতে পারেন।

ভাগ্য সুপ্রসন্ন হোক!


কিছু সময় লুপ ব্যবহার করুন, এটির মতো:

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

নোট:

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

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

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


ধরুন আপনার কাছে এই ফাইল আছে:

$ 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. লাইন 6 একটি সিআর সঙ্গে বাতিল করা হয় না।

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

এখানে এমন পদ্ধতিগুলি রয়েছে যা ফাইলটি পরিবর্তন করতে পারে ( 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 -rp; 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) থেকে " মুছে ফেলেন তবে আপনি শব্দটি শব্দটি একটি $(cat /tmp/test.txt) পরিবর্তে শব্দ দ্বারা পড়তে পারেন। সম্ভবত $(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 এর অধীনে ভাঙা বলে মনে করা হয়। যদি আপনি পিছনের দিকে গণনা করতে পারেন \n আপনাকে while লুপে || [[ -n $line ]] হয় না।)

আরো বাশ FAQ এ


#!/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

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




io