Bash හි ගොනුවක අන්තර්ගතය හරහා ලූප වීම


1419

පෙළ ගොනුවක එක් එක් පේළිය බාෂ් සමඟ නැවත කියවන්නේ කෙසේද?

මෙම පිටපත සමඟ:

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

20
ඔහ්, මෙහි බොහෝ දේ සිදුවී ඇති බව මට පෙනේ: සියලු අදහස් මකා දමා ප්‍රශ්නය නැවත විවෘත කරනු ලැබේ. යොමු කිරීම සඳහා, විචල්‍යයකට අගය පැවරීමෙන් රේඛාවක් කියවා ලිපිගොනු කියවීමෙහි පිළිගත් පිළිතුර කැනොනිකල් ආකාරයෙන් ගැටලුව විසඳන අතර මෙහි පිළිගත් පිළිතුරට වඩා වැඩි කැමැත්තක් දැක්විය යුතුය.
fedorqui 'SO හානිය නවත්වන්න'

Answers:


2141

එය කළ හැකි එක් ක්‍රමයක් නම්:

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 ට වඩා වෙනස්).


8
අවසාන පේළිය මා අර්ථ නිරූපණය කළ යුත්තේ කෙසේද? ගොනුව peptides.txt සම්මත ආදානය වෙත හරවා යවන අතර කෙසේ හෝ මුළු වාරණයටම?
පීටර් මෝර්ටෙන්සන්

11
"මේ අතරතුර ලූප් පෙප්ටයිඩස්. Sxt කරන්න, එබැවින් 'කියවන්න' විධානයට පරිභෝජනය කිරීමට යමක් තිබේ." මගේ "කැට්" ක්‍රමය සමාන වන අතර, විධානයක ප්‍රතිදානය 'කියවීම' මඟින් පරිභෝජනය සඳහා වන වාරණ වාරයට යවනු ලැබේ.
වොරන් යන්ග්

8
මෙම ක්‍රමය ගොනුවක අවසාන පේළිය මඟ හැර ඇති බව පෙනේ.
xastor

5
පේළි දෙගුණයක් උපුටා දක්වන්න !! echo "$ p" සහ ගොනුව .. මාව විශ්වාස කරන්න ඔබ එසේ නොකළහොත් එය ඔබට දෂ්ට කරනු ඇත !!! මම දන්නවා! lol
මයික් Q

7
නව රේඛාවක් සමඟ අවසන් නොවන්නේ නම් අනුවාද දෙකම අවසාන පේළියක් කියවීමට අසමත් වේ. සැමවිටම භාවිතා කරන්නwhile read p || [[ -n $p ]]; do ...
dawg

462
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
ඔව්, එය බ un නෝගේ තරම් කාර්යක්ෂම නොවේ, මන්ද එය අනවශ්‍ය ලෙස වෙනත් වැඩසටහනක් දියත් කරයි. කාර්යක්ෂමතාව වැදගත් නම්, එය බ un නෝගේ ක්‍රමය කරන්න. මට මගේ ක්‍රමය මතකයි ඔබට වෙනත් විධානයන් සමඟ එය භාවිතා කළ හැකි නිසා “සිට යළි හරවා යැවීම” සින්ටැක්ස් ක්‍රියා නොකරයි.
වොරන් යං

74
මේ සමඟ තවත් බරපතල ගැටළුවක් තිබේ: ලූපය නල මාර්ගයක කොටසක් බැවින් එය උප කුලකයක ධාවනය වන අතර එම නිසා ලූපය තුළ ඇති ඕනෑම විචල්‍යයක් පිටවන විට නැති වී යයි (බලන්න bash-hackers.org/wiki/doku. php / mirroring / bashfaq / 024 ). මෙය ඉතා කරදරකාරී විය හැකිය (ඔබ ලූපය තුළ කිරීමට උත්සාහ කරන දේ අනුව).
ගෝර්ඩන් ඩේවිසන්

25
මගේ විධාන බොහොමයක ආරම්භය ලෙස මම "cat file |" භාවිතා කරමි, මන්ද මම බොහෝ විට "head file |"
mat kelcey

63
මෙය එතරම් කාර්යක්ෂම නොවිය හැකි නමුත් එය වෙනත් පිළිතුරු වලට වඩා කියවිය හැකිය.
සැවේජ් රීඩර්

146

විකල්පය 1a: ලූප අතර: වරකට තනි පේළිය: ආදාන යළි හරවා යැවීම

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

විකල්පය 1b: ලූප අතර: වරකට තනි පේළිය:
ගොනුව විවෘත කරන්න, ගොනු විස්තර කරන්නෙකුගෙන් කියවන්න (මෙම අවස්ථාවේදී ගොනු විස්තරය # 4).

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

1b විකල්පය සඳහා: ගොනු විස්තරය නැවත වසා දැමිය යුතුද? උදා: ලූපය අභ්‍යන්තර පුඩුවක් විය හැකිය.
පීටර් මෝර්ටෙන්සන්

3
ක්‍රියාවලියෙන් පිටවීමත් සමඟ ගොනු විස්තරය පිරිසිදු කෙරේ. Fd අංකය නැවත භාවිතා කිරීම සඳහා පැහැදිලි සමීපයක් කළ හැකිය. Fd එකක් වැසීමට, & - සින්ටැක්ස් සමඟ තවත් ක්‍රියාත්මක කරන්න, මේ ආකාරයට: exec 4 <& -
ස්ටැන් ග්‍රේව්ස්

1
විකල්ප 2 ට ස්තූතියි. මම විකල්පය 1 සමඟ විශාල ගැටලුවලට මුහුණ දුන්නෙමි. එවැනි අවස්ථාවකදී විකල්ප 1 ක්‍රියාත්මක නොවේ.
masgo

4
විකල්ප 2 දැඩි ලෙස අධෛර්යමත් වී ඇති බව ඔබ වඩාත් පැහැදිලිව පෙන්වා දිය යුතුය . @masgo ඔප්ෂන් 1 ආ එම නඩුව කටයුතු කළ යුතු අතර, වෙනුවට ඔප්ෂන් 1 අ සිට ආදාන හරවා යැවීමේ කාරක රීති සමග ඒකාබද්ධ කළ හැකි done < $filenameසමග done 4<$filenameඔබ විස්ථාපනය කල හැකි අතර එසේ වුවහොත් (ඔබ විධාන පරාමිතිය සිට ගොනු නාමය කියවීමට අවශ්ය නම් ප්රයෝජනවත් වන, $filenameවිසින් $1).
ඊගෝර් හාන්ස්

ලූපය tail -n +2 myfile.txt | grep 'somepattern' | cut -f3තුළ ssh විධාන ක්‍රියාත්මක කරන අතරතුර (stdin පරිභෝජනය කරයි) වැනි ගොනු අන්තර්ගතයන් හරහා මට ලූප් කිරීමට අවශ්‍යය ; මෙහි 2 වන විකල්පය එකම ක්‍රමය ලෙස පෙනේ?
user5359531

90

මෙය වෙනත් පිළිතුරු වලට වඩා හොඳ නැත, නමුත් අවකාශයක් නොමැතිව ගොනුවක කාර්යය ඉටු කිරීමට තවත් එක් ක්‍රමයකි (අදහස් බලන්න). වෙනම ස්ක්‍රිප්ට් ලිපිගොනු භාවිතා කිරීමේ අමතර පියවරක් නොමැතිව පෙළ ගොනුවල ලැයිස්තු හෑරීමට මට බොහෝ විට එක්-ලයිනර් අවශ්‍ය බව මට පෙනී ගියේය.

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

මෙම ආකෘතිය මට එක විධාන රේඛාවකට දැමීමට ඉඩ දෙයි. "Echo $ word" කොටස ඔබට අවශ්‍ය ඕනෑම දෙයකට වෙනස් කරන්න, ඔබට අර්ධ සළකුණු වලින් වෙන් කරන ලද විධාන කිහිපයක් නිකුත් කළ හැකිය. පහත උදාහරණයෙන් ඔබ ලියා ඇති වෙනත් ස්ක්‍රිප්ට් දෙකකට තර්ක ලෙස ගොනුවේ අන්තර්ගතය භාවිතා කරයි.

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

නැතහොත් ඔබ මෙය ධාරා සංස්කාරකයක් ලෙස භාවිතා කිරීමට අදහස් කරන්නේ නම් (ඉගෙන ගන්න sed) ඔබට පහත පරිදි ප්‍රතිදානය වෙනත් ගොනුවකට දැමිය හැකිය.

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
Bash <(<peptides.txt) සමහර විට වඩාත් අලංකාරයි, නමුත් එය තවමත් වැරදියි, ජොආඕ පැවසූ දේ නිවැරදිව, ඔබ කරන්නේ විධාන ආදේශන තර්කනයකි, එහිදී අවකාශය හෝ නව රේඛාව එකම දෙයයි. රේඛාවකට එහි ඉඩක් තිබේ නම්, ලූපය එම එක් පේළියක් සඳහා TWICE හෝ ඊට වැඩි ප්‍රමාණයක් ක්‍රියාත්මක කරයි. එබැවින් ඔබේ කේතය නිසියාකාරව කියවිය යුතුය: word (<peptides.txt) හි වචනය සඳහා; කරන්න .... අවකාශයක් නොමැති බව ඔබ දන්නේ නම්, රේඛාවක් වචනයකට සමාන වන අතර ඔබ හොඳින්.
maxpolk

2
@ ජොආකොස්ටා, මැක්ස්පොක්: මම නොසිතූ හොඳ කරුණු. ඒවා පිළිබිඹු කිරීම සඳහා මම මුල් ලිපිය සංස්කරණය කළෙමි. ස්තූතියි!
mightypile

2
භාවිතා forකිරීම ආදාන ටෝකන / රේඛා ෂෙල් ප්‍රසාරණයට යටත් කරයි, එය සාමාන්‍යයෙන් නුසුදුසු ය; මෙය උත්සාහ කරන්න: for l in $(echo '* b c'); do echo "[$l]"; done- ඔබ දකින පරිදි, *- මුලින් උපුටා ගත් වචනාර්ථයක් වුවද - වත්මන් නාමාවලියෙහි ඇති ගොනු වෙත පුළුල් වේ.
mklement0

2
bdblanchard: අවසාන උදාහරණය, ​​$ IFS භාවිතා කරමින් අවකාශය නොසලකා හැරිය යුතුය. ඔබ එම අනුවාදය උත්සාහ කර තිබේද?
mightypile

4
තීරණාත්මක ගැටළු නිරාකරණය කර ඇති බැවින් මෙම විධානය වඩාත් සංකීර්ණ වන ආකාරය, forගොනු රේඛා නැවත සැකසීමට භාවිතා කිරීම නරක අදහසකි. ප්ලස්, @ mklement0 විසින් සඳහන් කර ඇති පුළුල් කිරීමේ අංගය (පැන ගිය උපුටා දැක්වීම් ගෙන ඒමෙන් එය මඟ හැරිය හැකි වුවද, එය නැවත දේවල් වඩාත් සංකීර්ණ හා කියවිය නොහැකි ලෙස අඩු කරයි).
ඊගෝර් හාන්ස්

70

වෙනත් පිළිතුරු වලින් ආවරණය නොවන තවත් කරුණු කිහිපයක්:

වෙන් කරන ලද ගොනුවකින් කියවීම

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

සම්පූර්ණ ගොනුවක් අරාවකට කියවීම (Bash අනුවාද 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)
masterxilo

1
ගොනුව අරාව තුළට කියවීමට ස්තූතියි. මට අවශ්‍ය දේ හරියටම, මට එක් එක් පේළිය දෙවරක් විග්‍රහ කිරීමට, නව විචල්‍යයන්ට එකතු කිරීමට, සමහර වලංගු කිරීම් කිරීමට අවශ්‍ය නිසා
frank_108

මෙය මා සිතන වඩාත්ම ප්‍රයෝජනවත් අනුවාදයයි
user5359531

45

මේ ආකාරයට කෙටි ලූපයක් භාවිතා කරන්න:

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

සටහන්:

  1. ඔබ IFSනිසියාකාරව සකසා නොමැති නම්, ඔබට ඉන්ඩෙන්ෂන් නැති වේ.

  2. ඔබ සෑම විටම පාහේ කියවීම සමඟ -r විකල්පය භාවිතා කළ යුතුය.

  3. සමඟ පේළි කියවන්න එපා for


2
ඇයි -rවිකල්පය?
ඩේවිඩ් සී. රැන්කින්

2
@ ඩේවිඩ් සී. රැන්කින් -r විකල්පය බැක්ස්ලෑෂ් අර්ථ නිරූපණය වළක්වයි. Note #2එය විස්තරාත්මකව විස්තර කර ඇති සබැඳියකි ...
ජාහිඩ්

මෙය වෙනත් පිළිතුරක "කියවීම -u" විකල්පය සමඟ ඒකාබද්ධ කර එය පරිපූර්ණයි.
ෆ්ලොරින් ඇන්ඩ්‍රි

LorFlorinAndrei: ඉහත උදාහරණයට -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 වන පේළිය CR ​​සමඟ අවසන් නොවේ.

ඔබට සීආර් නොමැතිව හිස් රේඛා සහ අවසන් රේඛා ඇතුළුව පෙළ ගොනු රේඛාව අවශ්‍ය නම්, ඔබ ටික වේලාවක් භාවිතා කළ යුතු අතර අවසාන පේළිය සඳහා විකල්ප පරීක්ෂණයක් තිබිය යුතුය.

ගොනුව වෙනස් කළ හැකි ක්‍රම මෙන්න ( 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වෙනුවට කරන්නේ නම් , ඔබ ප්‍රමුඛ හා පසුපස අවකාශයන් ආරක්ෂා කරයි, නමුත් CR සමඟ අවසන් නොවන්නේ නම් අවසාන පේළිය තවමත් අහිමි වේ)

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

8
මෙම පිළිතුරට මයිටිපයිල්ගේ පිළිතුරෙහි සඳහන් කර ඇති අවවාද අවශ්‍ය වන අතර , ඕනෑම පේළියක ෂෙල් මෙටාචරැක්ටර්ස් තිබේ නම් එය නරක ලෙස අසමත් විය හැකිය (නම් නොකල "$ x" නිසා).
ටෝබි ස්පයිට්

8
මම ඇත්තටම ඉන්නේ පුදුම ජනතාව තවමත් සුපුරුදු සමග ආවේ නැහැ සඳහා සමග රැහැන් කියවන්න එපා ...
Egor හාන්ස්

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 පේළි ගොනු හා එසේ ම ක ආරම්භයේ සිට tailවිධානය පහල සිට කියවීමට භාවිතා කළ හැක. දැන්, ගොනුවෙන් n වන පේළිය ලබා ගැනීම සඳහා, අපි රේඛා n වෙතට යමු , දත්ත වලිගයට නල මාර්ගයෙන් නල දත්ත වලින් පේළි 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

2
මෙය නොකරන්න. රේඛා අංක හරහා ලූප කිරීම සහ එක් එක් රේඛාව sedහෝ head+ මාර්ගයෙන් ලබා tailගැනීම ඇදහිය නොහැකි තරම් අකාර්යක්ෂම වන අතර ඇත්ත වශයෙන්ම ඔබ මෙහි වෙනත් විසඳුම් වලින් එකක් භාවිතා නොකරන්නේ මන්ද යන ප්‍රශ්නය අසයි. ඔබට රේඛා අංකය දැන ගැනීමට අවශ්‍ය නම්, ඔබේ while read -rලූපයට කවුන්ටරයක් ​​එක් කරන්න , නැතහොත් nl -baලූපයට පෙර එක් එක් පේළියට රේඛා අංක උපසර්ගයක් එක් කිරීමට භාවිතා කරන්න.
ත්‍රිත්ව

0

මම xargsඒ වෙනුවට භාවිතා කිරීමට කැමතියි while. xargsබලවත් සහ විධාන රේඛා හිතකාමී වේ

cat peptides.txt | xargs -I % sh -c "echo %"

සමඟ xargs, ඔබට සමඟ වාචිකතාව -tසහ වලංගුභාවය එකතු කළ හැකිය-p


-1

Et පීටර්: මෙය ඔබට ප්‍රයෝජනවත් විය හැකිය-

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

මෙය ප්‍රතිදානය නැවත ලබා දෙනු ඇත-

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


3
මෙම පිළිතුර ඉහත හොඳ පිළිතුරු මගින් සකසා ඇති සියලුම මූලධර්ම පරාජය කිරීමකි!
codeforester

3
කරුණාකර මෙම පිළිතුර මකන්න.
dawg

3
දැන් යාලුවනේ, අතිශයෝක්තියට නංවන්න එපා. පිළිතුර නරක ය, නමුත් එය ක්‍රියාත්මක වන බව පෙනේ, අවම වශයෙන් සරල භාවිත අවස්ථා සඳහා. එය සපයා ඇති තාක් කල්, නරක පිළිතුරක් වීම පිළිතුරේ පැවැත්මට ඇති අයිතිය පැහැර නොගනී.
ඊගෝර් හාන්ස්

3
G ඊගෝර්හාන්ස්, මම තදින්ම එකඟ නොවෙමි: පිළිතුරු සැපයීමේ කාරණය වන්නේ මෘදුකාංග ලිවිය යුතු ආකාරය ජනතාවට ඉගැන්වීමයි. ඔබ දන්නා ආකාරයට දේවල් කිරීමට මිනිසුන්ට ඉගැන්වීම ඔවුන්ට හානිකර වන අතර ඔවුන්ගේ මෘදුකාංග භාවිතා කරන පුද්ගලයින් (දෝෂ / අනපේක්ෂිත හැසිරීම් / ආදිය හඳුන්වා දීම) දැනුවත්ව අන් අයට හානි කරයි. හානිකර යැයි දන්නා පිළිතුරකට හොඳින් ඉගැන්වූ සම්පතක් තුළ “පැවැත්මට අයිතියක් නැත” (සහ එය සුවපත් කිරීම යනු ඡන්දය ප්‍රකාශ කිරීම සහ සලකුණු කිරීම සිදුකරන ජනතාව වන අපි මෙහි කළ යුතු දෙයයි).
චාල්ස් ඩෆි
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.