बैश में एक फ़ाइल की सामग्री के माध्यम से लूपिंग


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केवल स्क्रीन के उत्पादन की तुलना में कुछ अधिक जटिल करना चाहता हूं ।)


पर्यावरण चर शेल (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 (geeko@buildhost) (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

19
ओह, मैं देख रहा हूं कि कई चीजें यहां हुई हैं: सभी टिप्पणियों को हटा दिया गया था और प्रश्न को फिर से खोल दिया गया था। केवल संदर्भ के लिए, एक चर के मान को निर्दिष्ट करने वाली लाइन द्वारा एक फ़ाइल लाइन पढ़ें में स्वीकार किए गए उत्तर को कैनोनिकल तरीके से समस्या को संबोधित किया जाता है और यहां स्वीकृत एक पर प्राथमिकता दी जानी चाहिए।
फेडोरक्वी 'एसओ स्टॉप हॉर्मिंग'

जवाबों:


2089

इसे करने का एक तरीका है:

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
मुझे अंतिम पंक्ति की व्याख्या कैसे करनी चाहिए? फ़ाइल peptides.txt को मानक इनपुट पर पुनर्निर्देशित किया गया है और किसी तरह पूरे ब्लॉक में?
पीटर मोर्टेंसन

11
"स्लिप पेप्टाइड्स। इस में लूप करते समय, इसलिए 'रीड' कमांड के पास उपभोग करने के लिए कुछ है।" मेरी "बिल्ली" विधि समान है, 'रीड' द्वारा खपत के लिए थोड़ी देर के ब्लॉक में एक कमांड का आउटपुट भेजना, भी, यह केवल एक और प्रोग्राम लॉन्च करता है ताकि काम पूरा हो सके।
वॉरेन यंग

8
यह विधि किसी फ़ाइल की अंतिम पंक्ति को छोड़ती प्रतीत होती है।
xastor

5
डबल लाइन की बोली !! इको "$ पी" और फ़ाइल .. मुझे विश्वास है कि यह आपको काटेगा यदि आप नहीं करते हैं !!! मुझे पता है! लोल
माइक क्यू

5
दोनों संस्करण एक अंतिम पंक्ति को पढ़ने में विफल होते हैं यदि इसे एक नई रेखा के साथ समाप्त नहीं किया जाता है। हमेशा इस्तेमाल करते हैंwhile read p || [[ -n $p ]]; do ...
dawg

447
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
सामान्य तौर पर, यदि आप केवल एक तर्क के साथ "बिल्ली" का उपयोग कर रहे हैं, तो आप कुछ गलत कर रहे हैं (या उप-विषयक)।
जेसपेरे 18

27
हां, यह सिर्फ ब्रूनो की तरह कुशल नहीं है, क्योंकि यह अनावश्यक रूप से एक और कार्यक्रम शुरू करता है। यदि दक्षता मायने रखती है, तो इसे ब्रूनो के तरीके से करें। मुझे अपना रास्ता याद है क्योंकि आप इसे अन्य कमांड के साथ उपयोग कर सकते हैं, जहां "सिंटैक्स इन" से सिंटैक्स काम नहीं करता है।
वॉरेन यंग

74
इसके साथ एक और गंभीर समस्या है: क्योंकि जब लूप एक पाइपलाइन का हिस्सा होता है, तो यह एक उप-भाग में चलता है, और इसलिए जब यह बाहर निकलता है तो लूप के अंदर सेट किया गया कोई भी चर खो जाता है (देखें bash-hackers.org/wiki/doku। php / मिररिंग / bashfaq / 024 )। यह बहुत कष्टप्रद हो सकता है (आप लूप में क्या करने की कोशिश कर रहे हैं इसके आधार पर)।
गॉर्डन डेविसन

25
मैं "मेरे बहुत से कमांड्स की शुरुआत के रूप में" कैट फाइल का उपयोग करता है, क्योंकि मैं अक्सर "हेड फाइल" के साथ प्रोटोटाइप करता हूं।
चटाई kelcey

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
फ़ाइल डिस्क्रिप्टर को प्रक्रिया से बाहर निकलने के साथ साफ किया जाएगा। Fd संख्या का पुन: उपयोग करने के लिए एक स्पष्ट करीबी किया जा सकता है। एक fd को बंद करने के लिए, & - सिंटैक्स के साथ एक अन्य निष्पादन का उपयोग करें, जैसे: 4 <और -
स्टेन ग्रेव्स

1
विकल्प 2 के लिए धन्यवाद। मैं विकल्प 1 के साथ बड़ी समस्याओं में भाग गया क्योंकि मुझे लूप के भीतर स्टड से पढ़ने की आवश्यकता थी; ऐसे मामले में विकल्प 1 काम नहीं करेगा।
मसलन

4
आपको अधिक स्पष्ट रूप से इंगित करना चाहिए कि विकल्प 2 दृढ़ता से हतोत्साहित है । @masgo विकल्प 1b उस मामले में काम करना चाहिए, और की जगह विकल्प 1a से इनपुट पुनर्निर्देशन वाक्य रचना के साथ जोड़ा जा सकता है done < $filenameके साथ done 4<$filename(जो आप एक आदेश पैरामीटर से फ़ाइल नाम पढ़ना चाहते हैं के लिए उपयोगी है, जो मामले में आप सिर्फ जगह ले सकता है $filenameद्वारा $1)।
ईगोर हंस

मुझे फ़ाइल सामग्री पर लूप करने की आवश्यकता है जैसे tail -n +2 myfile.txt | grep 'somepattern' | cut -f3, लूप के अंदर ssh कमांड को चलाने के दौरान (स्टड का उपभोग करता है); विकल्प 2 यहां एकमात्र तरीका प्रतीत होता है?
user5359531

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
बाश $ (<peptides.txt) शायद अधिक सुरुचिपूर्ण है, लेकिन यह अभी भी गलत है, जोआओ ने सही कहा, आप कमांड प्रतिस्थापन तर्क का प्रदर्शन कर रहे हैं जहां अंतरिक्ष या न्यूलाइन एक ही बात है। यदि किसी पंक्ति में एक स्थान है, तो लूप उस एक पंक्ति के लिए TWICE या अधिक का निष्पादन करता है। तो आपका कोड ठीक से पढ़ना चाहिए: शब्द में $ के लिए (<peptides.txt); do .... यदि आप एक तथ्य के लिए जानते हैं कि कोई स्थान नहीं है, तो एक पंक्ति एक शब्द के बराबर होती है और आप ठीक हैं।
अधिकतमपुलिस

2
@ जोआकोस्टा, मैक्सपोल्क: अच्छे बिंदु जिन्हें मैंने नहीं माना था। मैंने उन्हें प्रतिबिंबित करने के लिए मूल पोस्ट को संपादित किया है। धन्यवाद!
mightypile

2
का उपयोग करना forइनपुट टोकन / लाइनों को शेल विस्तार के अधीन बनाता है, जो आमतौर पर अवांछनीय है; इसे आज़माएँ: for l in $(echo '* b c'); do echo "[$l]"; done- जैसा कि आप देखेंगे, *- भले ही मूल रूप से एक उद्धृत शाब्दिक है - वर्तमान निर्देशिका में फ़ाइलों तक फैलता है।
mklement0

2
@dblanchard: $ IFS का उपयोग करते हुए अंतिम उदाहरण, रिक्त स्थान को अनदेखा करना चाहिए। क्या आपने उस संस्करण की कोशिश की है?
मई

4
जिस तरह से यह कमांड बहुत अधिक जटिल हो जाती है, क्योंकि महत्वपूर्ण मुद्दे तय हो जाते हैं, बहुत अच्छी तरह से प्रस्तुत करता है कि क्यों forइटैल्ट फ़ाइल लाइनों का उपयोग करना एक बुरा विचार है। इसके अलावा, @ mklement0 (भले ही शायद बच गए उद्धरणों में लाकर, जिसे फिर से चीजों को और अधिक जटिल और कम पठनीय बना दिया जा सकता है) द्वारा वर्णित विस्तार पहलू।
हंस

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)

संबंधित पढ़ें: BashFAQ / 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

आधार पर @ chepner के जवाब यहाँ :

-uएक बैश एक्सटेंशन है। POSIX संगतता के लिए, प्रत्येक कॉल कुछ ऐसा दिखाई देगा 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 15

45

कुछ समय लूप का उपयोग करें, जैसे:

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

टिप्पणियाँ:

  1. यदि आप IFSठीक से सेट नहीं करते हैं , तो आप इंडेंटेशन खो देंगे।

  2. आपको रीड के साथ लगभग हमेशा -r विकल्प का उपयोग करना चाहिए।

  3. लाइनों के साथ पढ़ा नहीं है for


2
-rविकल्प क्यों ?
डेविड सी। रंकिन

2
@ DavidC.Rankin -r विकल्प बैकस्लैश व्याख्या को रोकता है। Note #2एक कड़ी है, जहाँ इसका विस्तार से वर्णन किया गया है ...
जाहिद

इसे दूसरे उत्तर में "रीड -यू" विकल्प के साथ मिलाएं और फिर यह एकदम सही है।
फ्लोरिन आंद्रेई

@FlorinAndrei: उपरोक्त उदाहरण को -uविकल्प की आवश्यकता नहीं है , क्या आप दूसरे उदाहरण के बारे में बात कर रहे हैं -u?
जाहिद

आपके लिंक के माध्यम से देखा, और आश्चर्य हुआ कि कोई जवाब नहीं है जो केवल नोट 2 में आपके लिंक को लिंक करता है। यह पृष्ठ आपको उस विषय के बारे में जानने के लिए आवश्यक सब कुछ प्रदान करता है। या लिंक-केवल उत्तर हतोत्साहित या कुछ हैं?
ईगोर हंस

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. पंक्ति 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 -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 के तहत टूट माना जाता है। आप अनुगामी पर भरोसा कर सकते हैं \nआप की जरूरत नहीं है || [[ -n $line ]]में whileपाश।)

BASH अकसर किये गए सवाल पर अधिक


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
जबकि उत्तर सही है, मुझे समझ में नहीं आया कि यह यहाँ कैसे समाप्त हुआ। आवश्यक विधि कई अन्य उत्तरों द्वारा प्रस्तावित के समान है। साथ ही, यह आपके FPS उदाहरण में पूरी तरह से डूब जाता है।
हंस

0

यह बहुत देर से आ रहा है, लेकिन इस विचार के साथ कि यह किसी की मदद कर सकता है, मैं जवाब जोड़ रहा हूं। इसके अलावा यह सबसे अच्छा तरीका नहीं हो सकता है। headकमांड का उपयोग फ़ाइल की शुरुआत से n लाइनों-n को पढ़ने के लिए तर्क के साथ किया जा सकता है और इसी तरह नीचे से पढ़ने के लिए कमांड का उपयोग किया जा सकता है। अब, फ़ाइल से nth लाइन लाने के लिए , हम n n हेड लाइन करते हैं , पाइप किए गए डेटा से केवल 1 लाइन पूंछने के लिए डेटा को पाइप करते हैं। tail

   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
यह मत करो। लाइन नंबर से अधिक पाशन और के माध्यम से प्रत्येक व्यक्ति लाइन प्राप्त करने में कठिनाई sedया head+ tailहै अविश्वसनीय रूप से अक्षम, और निश्चित रूप से सवाल क्यों आप बस यहां अन्य समाधानों में से एक का उपयोग नहीं करते भीख माँगता। यदि आपको पंक्ति संख्या जानने की आवश्यकता है, तो अपने while read -rपाश में एक काउंटर जोड़ें , या nl -baलूप से पहले प्रत्येक पंक्ति में एक पंक्ति संख्या उपसर्ग जोड़ने के लिए उपयोग करें।
ट्रिपल

-1

@Peter: यह आपके लिए काम कर सकता है-

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

इससे आउटपुट वापस आएगा-

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


3
यह उत्तर ऊपर दिए गए अच्छे उत्तरों द्वारा निर्धारित सभी सिद्धांतों को हरा रहा है!
कोडफैस्टर

3
कृपया इस उत्तर को हटा दें।
dawg

3
अब लोग, अतिशयोक्ति न करें। उत्तर बुरा है, लेकिन यह काम करने लगता है, कम से कम सरल उपयोग के मामलों के लिए। जब तक यह प्रदान किया जाता है, तब तक एक बुरा उत्तर होने के कारण उत्तर का अधिकार मौजूद नहीं होता है।
ईगोर हंस

3
@ EgorHans, मैं दृढ़ता से असहमत हूँ: उत्तरों की बात यह है कि लोगों को सॉफ्टवेयर लिखना सिखाया जाए। लोगों को इस तरह से चीजों को करने के लिए सिखाना जो आप जानते हैं कि उनके लिए हानिकारक है और वे लोग जो अपने सॉफ़्टवेयर का उपयोग करते हैं (बग / अनपेक्षित व्यवहार / आदि का परिचय देते हैं) जानबूझकर दूसरों को नुकसान पहुंचा रहे हैं। एक उत्तर के रूप में जाना जाता हानिकारक होने के लिए एक अच्छी तरह से घुमावदार शिक्षण संसाधन में "अस्तित्व का अधिकार" नहीं है (और यह क्यूरेटिंग वही है जो हम, जो लोग मतदान कर रहे हैं और झंडा लगा रहे हैं, वे यहां कर रहे हैं)।
चार्ल्स डफी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.