පෙළ සැකසීමට ෂෙල් ලූපයක් භාවිතා කිරීම නරක පුරුද්දක් ලෙස සලකන්නේ ඇයි?


208

පෙළ සැකසීම සඳහා කාල ලූපයක් භාවිතා කිරීම පොසික්ස් කවච වල නරක පුරුද්දක් ලෙස සලකන්නේද?

ලෙස Stéphane Chazelas පෙන්වා , සිප්පි කටු, චක්රයක් සඳහා භාවිතා නොකිරීමට හේතු කිහිපයකි සංකල්පීය , විශ්වසනීයත්වය , legibility , කාර්ය සාධනය සහ ආරක්ෂක .

මෙම පිළිතුර පැහැදිලි විශ්වසනීයත්වය හා legibility අංශ:

while IFS= read -r line <&3; do
  printf '%s\n' "$line"
done 3< "$InputFile"

සඳහා කාර්ය සාධන , එම whileලූපය හා කියවීමේ අවශ්යතාව විශාල මන්දගාමී ගොනුව හෝ නල සිට කියවන විට, එම නිසා ය බිල්ට් කියවා ෂෙල් වරකට එක චරිත කියවනවා.

ආකාරය පිළිබඳ සංකල්පීය හා ආරක්ෂක අංශ?



5
කියවන කවචය තුළ එක අක්‍ෂරයක් එකවර කියවන්නේ නැත, එය වරකට එක පේළියක් කියවයි. wiki.bash-hackers.org/commands/builtin/read
A. ඩැනිස්චෙව්ස්කි

@ A. ඩැනිස්චෙව්ස්කි: එය ඔබේ කවචය මත රඳා පවතී. තුළ bash, එය වරකට එක් ස්වාරක්ෂක ප්‍රමාණයක් කියවයි, dashඋදාහරණයක් ලෙස උත්සාහ කරන්න . Unix.stackexchange.com/q/209123/38906
cuonglm

Answers:


272

ඔව්, අපි බොහෝ දේ දකිමු:

while read line; do
  echo $line | cut -c3
done

හෝ ඊට වඩා නරක:

for line in `cat file`; do
  foo=`echo $line | awk '{print $2}'`
  echo whatever $foo
done

(සිනාසෙන්න එපා, මම ඒවායින් බොහොමයක් දැක ඇත්තෙමි).

සාමාන්‍යයෙන් ෂෙල් ස්ක්‍රිප්ටින් ආරම්භකයින්ගෙන්. ඒවා සී හෝ පයිතන් වැනි අත්‍යවශ්‍ය භාෂාවලින් ඔබ කරන දේ පිළිබඳ බොළඳ වචනමය පරිවර්තන වේ, නමුත් ඔබ ෂෙල් වෙඩි වලින් දේවල් කරන්නේ එලෙස නොවේ, එම උදාහරණ ඉතා අකාර්යක්ෂම, සම්පූර්ණයෙන්ම විශ්වාස කළ නොහැකි (ආරක්ෂක ගැටළු වලට තුඩු දිය හැකි) සහ ඔබ කවදා හෝ කළමනාකරණය කරන්නේ නම් බොහෝ දෝෂ නිවැරදි කිරීමට, ඔබේ කේතය අවිනිශ්චිත වේ.

සංකල්පමය වශයෙන්

සී හෝ වෙනත් බොහෝ භාෂාවලින්, ගොඩනැඟිලි කොටස් පරිගණක උපදෙස් වලට වඩා එක් මට්ටමකි. ඔබ ඔබේ ප්‍රොසෙසරයට කුමක් කළ යුතුද, ඊළඟට කුමක් කළ යුතුද යන්න පවසන්න. ඔබ ඔබේ ප්‍රොසෙසරය අතින් ගෙන එය ක්ෂුද්‍ර කළමනාකරණය කරයි: ඔබ එම ගොනුව විවෘත කරයි, ඔබ බොහෝ බයිට් කියවන බව කියවයි, ඔබ මෙය කරයි, ඔබ එය කරන්නේ එයයි.

ෂෙල් වෙඩි යනු ඉහළ මට්ටමේ භාෂාවකි. කෙනෙකුට කියන්න පුළුවන් එය භාෂාවක්වත් නැහැ කියලා. ඔවුන් සියලු විධාන රේඛා පරිවර්තකයන්ට පෙරය. කාර්යය සිදු කරනු ලබන්නේ ඔබ ක්‍රියාත්මක කරන විධානයන් මගිනි. කවචය යනු ඒවා මෙහෙයවීම පමණි.

යුනික්ස් විසින් හඳුන්වා දුන් විශිෂ්ටතම දෙය නම් නල සහ සියලු විධාන පෙරනිමියෙන් හසුරුවන පෙරනිමි stdin / stdout / stderr ප්‍රවාහයන් ය.

වසර 50 ක් තුළ, විධානවල බලය උපයෝගී කර ගැනීමටත් ඒවා යම් කාර්යයකට සහයෝගය දැක්වීමටත් අපි ඒපීඅයි වලට වඩා හොඳ සොයාගෙන නැත. අදටත් මිනිසුන් ෂෙල් වෙඩි භාවිතා කිරීමට ප්‍රධාන හේතුව එය විය හැකිය.

ඔබට කැපුම් මෙවලමක් සහ අක්ෂර පරිවර්තන මෙවලමක් ඇත, ඔබට සරලවම කළ හැකිය:

cut -c4-5 < in | tr a b > out

කවචය කරන්නේ ජලනල (ලිපිගොනු විවෘත කිරීම, පයිප්ප සැකසීම, විධාන ඉල්ලා සිටීම) සහ සියල්ල සූදානම් වූ විට එය කවදාවත් නොකර ෂෙල් එකකින් තොරව ගලා යයි. මෙවලම් ඔවුන්ගේ කාර්යය සමගාමීව, කාර්යක්ෂමව තමන්ගේම වේගයෙන් ප්‍රමාණවත් බෆරයකින් සිදු කරයි, එවිට එකක් අනෙකාට අවහිර නොකෙරේ, එය ලස්සන හා සරල ය.

මෙවලමක් යෙදවීම සඳහා පිරිවැයක් ඇතත් (අපි එය කාර්ය සාධන ලක්ෂ්‍යය මත සංවර්ධනය කරමු). එම මෙවලම් සී හි උපදෙස් දහස් ගණනක් සමඟ ලිවිය හැකිය. ක්‍රියාවලියක් නිර්මාණය කළ යුතුය, මෙවලම පැටවිය යුතුය, ආරම්භ කළ යුතුය, පසුව පිරිසිදු කළ යුතුය, ක්‍රියාවලිය විනාශ වී බලා සිටිය යුතුය.

ආයාචනා කිරීම cutයනු මුළුතැන්ගෙයි ලාච්චුව විවෘත කිරීම, පිහිය ගැනීම, භාවිතා කිරීම, සේදීම, වියළීම, නැවත ලාච්චුවේ තැබීම වැනි ය. ඔබ එසේ කරන විට:

while read line; do
  echo $line | cut -c3
done < file

එය ගොනුවේ සෑම පේළියකටම සමාන ය, readමුළුතැන්ගෙයි ලාච්චුවෙන් මෙවලම ලබා ගැනීම ( එය ඒ සඳහා නිර්මාණය කර නොමැති නිසා ඉතා අවුල් සහගත ), පේළියක් කියවීම, කියවීමේ මෙවලම සෝදා නැවත ලාච්චුවේ තබන්න. ඉන්පසු echoසහ cutමෙවලම සඳහා රැස්වීමක් උපලේඛනගත කරන්න , ඒවා ලාච්චුවෙන් ලබා ගන්න, ඒවාට ආරාධනා කරන්න, ඒවා සේදීම, වියළීම, නැවත ලාච්චුවේ තබන්න සහ යනාදිය.

එම මෙවලම් කිහිපයක් ( readහා echo) බොහෝ ෂෙල් වෙඩි ඉදි, නමුත් කිසිසේත් සිට මෙහි වෙනසක් බව ද echoහා cutතවමත් වෙනම ක්රියාවලි තුළ ක්රියාත්මක කළ යුතුයි.

එය හරියට ළූණු කපනවා වගේ නමුත් ඔබේ පිහිය සෝදා නැවත එක් එක් පෙත්තක් අතර මුළුතැන්ගෙයි ලාච්චුවේ තබන්න.

මෙන්න පැහැදිලිව පෙනෙන ක්‍රමය නම් ලාච්චුවෙන් ඔබේ cutමෙවලම ලබා ගැනීම, ඔබේ මුළු ළූණු පෙති කපන්න සහ සම්පූර්ණ කාර්යය අවසන් වූ පසු එය නැවත ලාච්චුවට දමන්න.

IOW, ෂෙල් වෙඩි වලින්, විශේෂයෙන් පෙළ සැකසීමට, ඔබ හැකි තරම් උපයෝගීතා කිහිපයක් ඉල්ලා සිටින අතර ඒවා කාර්යයට සහයෝගය දැක්විය යුතුය, ඊළඟ එක ක්‍රියාත්මක කිරීමට පෙර සෑම එකක්ම ආරම්භ කිරීමට, ධාවනය කිරීමට, පිරිසිදු කිරීමට බලා සිටින මෙවලම් දහස් ගණනක් අනුපිළිවෙලින් ධාවනය නොකරන්න.

ru ස්ගේ කදිම පිළිතුරෙන් වැඩිදුර කියවීම . ෂෙල් වෙඩි වල පහළ මට්ටමේ පෙළ සැකසුම් අභ්‍යන්තර මෙවලම් (සමහර විට හැර zsh) සීමිත, අවුල් සහගත සහ සාමාන්‍ය පෙළ සැකසුම් සඳහා නොගැලපේ.

කාර්ය සාධනය

කලින් කී පරිදි, එක් විධානයක් ධාවනය කිරීම සඳහා පිරිවැයක් දරයි. එම විධානය බිල්ඩින් නොවේ නම් විශාල පිරිවැයක්, නමුත් ඒවා ගොඩනඟා තිබුණත්, පිරිවැය විශාලය.

ෂෙල් වෙඩි එලෙස ධාවනය කිරීමට නිර්මාණය කර නැත, ඒවා ක්‍රියාකාරී ක්‍රමලේඛන භාෂාවන් බවට කිසිදු මවාපෑමක් නොමැත. ඔවුන් එසේ නොවේ, ඔවුන් විධාන රේඛා පරිවර්තකයන් පමණි. ඉතින්, මෙම පෙරමුණේ සුළු ප්රශස්තිකරණයක් සිදු කර ඇත.

එසේම, ෂෙල් වෙඩි වෙනම ක්‍රියාදාමයන්හි විධාන ක්‍රියාත්මක කරයි. එම ගොඩනැඟිලි කොටස් පොදු මතකයක් හෝ තත්වයක් බෙදා නොගනී. ඔබ C fgets()හෝ fputs()C කරන විට, එය stdio හි ශ්‍රිතයකි. බොහෝ විට මිල අධික පද්ධති ඇමතුම් වළක්වා ගැනීම සඳහා stdio සියළුම stdio කාර්යයන් සඳහා ආදානය සහ ප්‍රතිදානය සඳහා අභ්‍යන්තර බෆර තබා ගනී.

අනුරූප ෂෙල් උපයෝගිතා (පවා builtin read, echo, printf) ඒක කරන්න බැහැ. readඑක් පේළියක් කියවීමට අදහස් කෙරේ. එය නව රේඛා අක්‍ෂරය පසුකර කියවන්නේ නම්, එයින් අදහස් වන්නේ ඔබ ධාවනය කරන ඊළඟ විධානය එය මග හැරෙනු ඇති බවයි. ඒ නිසා readවරකට ආදානය එක් බයිට් එකක් කියවිය යුතුය (සමහර ක්‍රියාවට නැංවීම සාමාන්‍ය ගොනුවක් නම් ඒවා කුට්ටි කියවා ආපසු සොයනු ඇත, නමුත් එය ක්‍රියාත්මක වන්නේ සාමාන්‍ය ලිපිගොනු bashසඳහා පමණක් වන අතර උදාහරණයක් ලෙස කියවන්නේ බයිට් කුට්ටි 128 ක් පමණි තවමත් පෙළ උපයෝගිතා වලට වඩා බොහෝ අඩු වනු ඇත).

ප්‍රතිදාන පැත්තේ එකම, echoඑහි ප්‍රතිදානය බෆරයට දැමිය නොහැක, එය කෙළින්ම ප්‍රතිදානය කළ යුතුය, මන්ද ඔබ ධාවනය කරන ඊළඟ විධානය එම බෆරය බෙදා නොගනී.

නිසැකවම, විධාන අනුපිළිවෙලින් ක්‍රියාත්මක කිරීම යන්නෙන් අදහස් වන්නේ ඔබ ඔවුන් එනතෙක් බලා සිටිය යුතු බවයි, එය ෂෙල් එකෙන් සහ මෙවලම් සහ පසුපසට පාලනය ලබා දෙන කුඩා උපලේඛන නැටුමකි. එයින් අදහස් වන්නේ (නල මාර්ගයක දිගු කාලීන මෙවලම් භාවිතා කිරීමට වඩා වෙනස්ව) ඔබට එකවර සකසනයන් කිහිපයක් ලබා ගත නොහැකි බවයි.

එම while readලූපය හා (යැයි කියනු ලබන) සමාන cut -c3 < file, මගේ ඉක්මන් පරීක්ෂණයෙහි, මගේ පරීක්ෂණ වල CPU කාල අනුපාතය 40000 ක් පමණ වේ (තත්පරයට එදිරිව දිනකට අඩක්). නමුත් ඔබ ෂෙල් බිල්ඩින් පමණක් භාවිතා කළත්:

while read line; do
  echo ${line:2:1}
done

(මෙහි සමඟ bash), එය තවමත් 1: 600 ක් පමණ වේ (තත්පරයට මිනිත්තු 10 ක්).

විශ්වසනීයත්වය / පැහැදිලි බව

එම කේතය නිවැරදිව ලබා ගැනීම ඉතා අපහසුය. මා දුන් උදාහරණ බොහෝ විට වනයේ දක්නට ලැබේ, නමුත් ඒවාට බොහෝ දෝෂ තිබේ.

readවිවිධ දේ කළ හැකි පහසු මෙවලමකි. එයට පරිශීලකයාගෙන් ආදානය කියවිය හැකිය, විවිධ විචල්‍යයන්හි ගබඩා කිරීම සඳහා එය වචන වලට බෙදිය හැකිය. read lineනැහැ නැහැ , යෙදවුම් රේඛාවක් කියවන්න, හෝ සමහරවිට එය ඉතා විශේෂ ආකාරයකින් රේඛාවක් කියවනවා. එය ඇත්ත වශයෙන්ම ආදාන වලින් වචන කියවන අතර එම වචන වෙන් කොට $IFSඇති අතර බෙදුම්කරුවන්ගෙන් හෝ නව රේඛා අක්ෂරයෙන් ගැලවීමට බැක්ස්ලෑෂ් භාවිතා කළ හැකිය.

වැනි ආදානයක පෙරනිමි අගය සමඟ $IFS:

   foo\/bar \
baz
biz

read lineගබඩා කරනු ඇත "foo/bar baz"බවට $lineනැහැ, " foo\/bar \"ඔබ බලාපොරොත්තු කැමතියි ලෙස.

පේළියක් කියවීමට ඔබට සැබවින්ම අවශ්‍ය වන්නේ:

IFS= read -r line

එය එතරම් බුද්ධිමත් නොවේ, නමුත් එය එසේ ය, මතක තබා ගන්න ෂෙල් වෙඩි ඒ ආකාරයෙන් භාවිතා කිරීමට අදහස් නොකළ බව.

සඳහා එකම echo. echoඅනුපිළිවෙල පුළුල් කරයි. අහඹු ගොනුවක අන්තර්ගතය වැනි අත්තනෝමතික අන්තර්ගතයන් සඳහා ඔබට එය භාවිතා කළ නොහැක. printfඒ වෙනුවට ඔබට මෙහි අවශ්‍යයි .

ඇත්ත වශයෙන්ම, සෑම කෙනෙකුම වැටෙන ඔබේ විචල්‍යය උපුටා දැක්වීම සාමාන්‍යයෙන් අමතක වේ . එබැවින් එය තවත්:

while IFS= read -r line; do
  printf '%s\n' "$line" | cut -c3
done < file

දැන්, තවත් අවවාද කිහිපයක්:

  • හැර zsh, ආදානයේ NUL අක්ෂර අඩංගු වන්නේ නම් එය ක්‍රියා නොකරනු ඇති අතර අවම වශයෙන් GNU පෙළ උපයෝගිතා වලට ගැටලුවක් නොමැත.
  • අවසාන නව රේඛාවෙන් පසුව දත්ත තිබේ නම්, එය මඟ හරිනු ඇත
  • පුඩුවේ ඇතුළත, stdin යළි හරවා යවන බැවින් එහි ඇති විධානයන් stdin වෙතින් කියවන්නේ නැති බව ඔබ අවධානය යොමු කළ යුතුය.
  • ලූප තුළ ඇති විධාන සඳහා, ඒවා සාර්ථකද නැද්ද යන්න පිළිබඳව අපි අවධානය යොමු නොකරමු. සාමාන්‍යයෙන්, දෝෂ (තැටිය පිරී ඇත, කියවීමේ දෝෂ ...) කොන්දේසි දුර්වල ලෙස හසුරුවනු ඇත, සාමාන්‍යයෙන් නිවැරදි සමානතාවයට වඩා දුර්වල ලෙස .

ඉහත ගැටළු වලින් සමහරක් විසඳීමට අපට අවශ්‍ය නම්, එය මෙසේ වේ:

while IFS= read -r line <&3; do
  {
    printf '%s\n' "$line" | cut -c3 || exit
  } 3<&-
done 3< file
if [ -n "$line" ]; then
    printf '%s' "$line" | cut -c3 || exit
fi

එය අඩු වැඩි වශයෙන් පැහැදිලි වෙමින් පවතී.

තර්ක හරහා විධාන වෙත දත්ත යැවීම හෝ විචල්‍යයන් තුළ ඒවායේ ප්‍රතිදානය ලබා ගැනීම සමඟ තවත් ගැටළු ගණනාවක් තිබේ:

  • තර්කවල ප්‍රමාණයට ඇති සීමාව (සමහර පෙළ උපයෝගීතා ක්‍රියාවට නැංවීමේ සීමාවක් ද ඇත, නමුත් ළඟා වන අයගේ බලපෑම සාමාන්‍යයෙන් ගැටළු සහගත නොවේ)
  • NUL අක්ෂරය (පෙළ උපයෝගිතා සමඟ ද ගැටළුවක්).
  • තර්ක -(හෝ +සමහර විට) සමඟ ආරම්භ වන විට විකල්ප ලෙස ගනු ලැබේ
  • එම ලූපවල සාමාන්‍යයෙන් භාවිතා වන විවිධ විධානවල විවිධ විචක්ෂණ expr, test...
  • නොගැලපෙන ආකාරයෙන් බහු-බයිට් අක්ෂර හැසිරවිය හැකි විවිධ කවචවල (සීමිත) පෙළ හැසිරවීමේ ක්‍රියාකරුවන්.
  • ...

ආරක්ෂක කරුණු

ඔබ විධාන සඳහා ෂෙල් විචල්‍යයන් සහ තර්ක සමඟ වැඩ කිරීමට පටන් ගත් විට , ඔබ බිම් බෝම්බ ක්ෂේත්‍රයකට ඇතුළු වේ.

ඔබේ විචල්‍යයන් උපුටා දැක්වීමට ඔබට අමතක වුවහොත් , විකල්ප සලකුණුකරුවාගේ අවසානය අමතක කරන්න, බහු-බයිට් අක්ෂර සහිත ස්ථානවල වැඩ කරන්න (මේ දිනවල සම්මතය), ඉක්මනින් හෝ පසුව අවදානම් බවට පත්වන දෝෂ හඳුන්වා දීමට ඔබට විශ්වාසයි.

ඔබට ලූප භාවිතා කිරීමට අවශ්‍ය වූ විට.

ටී.බී.ඩී.


24
පැහැදිලි (විචිත්‍රවත්), කියවිය හැකි සහ අතිශයින්ම ප්‍රයෝජනවත්. නැවත වරක් ස්තූතියි. ෂෙල් ස්ක්‍රිප්ටින් සහ ක්‍රමලේඛනය අතර මූලික වෙනස සඳහා අන්තර්ජාලයේ ඕනෑම තැනක මා දැක ඇති හොඳම පැහැදිලි කිරීම මෙයයි.
වයිල්ඩ්කාඩ්

3
ආරම්භකයින්ට ෂෙල් ස්ක්‍රිප්ට් ගැන ඉගෙන ගැනීමට සහ එය සියුම් වෙනස්කම් දැකීමට උපකාරී වන මෙවැනි පෝස්ට් ය. ඔබට ශුන්‍යයක් නොලැබෙන බව සහතික කිරීම සඳහා යොමු කිරීමේ විචල්‍යය {AR VAR: -default_value as ලෙස එකතු කළ යුතුය. නිර්වචනය නොකළ අගයක් සඳහන් කිරීමේදී ඔබට කෑගැසීමට -o නාම පදයක් සකසන්න.
අත්සන් නොකළ

6
@ ඒ. ඩැනිස්චෙව්ස්කි, මම හිතන්නේ ඔබට කාරණය මග හැරී ඇත. ඔව් cutඋදාහරණයක් ලෙස කාර්යක්ෂමයි. cut -f1 < a-very-big-fileඔබ එය සී වලින් ලිවීමට කැමති නම් කාර්යක්ෂම, කාර්යක්ෂම වේ. ෂෙල් ලූපයක cuta a-very-big-fileහි සෑම පේළියකටම දරුණු අකාර්යක්ෂම හා දෝෂ ඇතිවිය හැකි දේ මෙම පිළිතුරේ සඳහන් වේ. අනවශ්‍ය කේතයක් ලිවීම පිළිබඳ ඔබේ අවසන් ප්‍රකාශයට එය එකඟ වන අතර එමඟින් ඔබේ අදහස මට නොතේරෙනු ඇතැයි මට සිතේ.
ස්ටෙෆාන් චසෙලාස්

5
"වසර 45 ක් තුළ, විධානවල බලය උපයෝගී කර ගැනීමටත් ඒවා යම් කාර්යයකට සහයෝගය දැක්වීමටත් අපි ඒපීඅයි එකට වඩා හොඳ සොයාගෙන නැත." - ඇත්ත වශයෙන්ම, පවර්ෂෙල්, බයිට් ප්‍රවාහයන්ට වඩා ව්‍යුහාත්මක දත්ත පසුකර යාමෙන් භයානක විග්‍රහ කිරීමේ ගැටළුව විසඳා ඇත. ෂෙල් වෙඩි තවමත් එය භාවිතා නොකිරීමට එකම හේතුව (අදහස සෑහෙන කාලයක් තිස්සේ පැවතුන අතර මූලික වශයෙන් ජාවා අවට දැන් සම්මත ලැයිස්තුව සහ ශබ්ද කෝෂ බහාලුම් වර්ග ප්‍රධාන ධාරාව බවට පත් වූ විට ස් st ටිකරූපී වී ඇත) ඔවුන්ගේ නඩත්තුකරුවන්ට තවමත් එකඟ විය නොහැක. භාවිතා කිරීමට පොදු ව්‍යුහාත්මක දත්ත ආකෘතිය (.
ivan_pozdeev

7
L ඔලිවියර් ඩියුලැක් මම හිතන්නේ ඒක ටිකක් හාස්‍යයක්. එම කොටස සදහටම ටී.බී.ඩී.
මුරු

43

සංකල්පීය හා පැහැදිලි බව අනුව, ෂෙල් වෙඩි සාමාන්‍යයෙන් ලිපිගොනු ගැන උනන්දු වෙයි. ඔවුන්ගේ "ලිපින කළ හැකි ඒකකය" ගොනුව වන අතර "ලිපිනය" යනු ගොනුවේ නමයි. ලිපිගොනු වල පැවැත්ම, ගොනු වර්ගය, ගොනු නාම හැඩතල ගැන්වීම (ගෝලීයකරණයෙන් ආරම්භ කිරීම) සඳහා ෂෙල් වෙඩි සඳහා සියලු ආකාර පරීක්ෂණ ක්‍රම තිබේ. ලිපිගොනු අන්තර්ගතය සමඟ කටයුතු කිරීම සඳහා ෂෙල් වෙඩි සතුව ඇත්තේ ඉතා ස්වල්පයක් පමණි. ගොනු අන්තර්ගතයන් සමඟ කටයුතු කිරීම සඳහා ෂෙල් ක්‍රමලේඛකයන්ට වෙනත් වැඩසටහනක් කැඳවිය යුතුය.

ගොනුව සහ ලිපිගොනු නාම දිශානතිය නිසා, ඔබ සඳහන් කළ පරිදි, කවචයේ පෙළ හැසිරවීම සැබවින්ම මන්දගාමී වන අතර, අපැහැදිලි සහ සමෝධානික ක්‍රමලේඛන ශෛලියක් ද අවශ්‍ය වේ.


26

සංකීර්ණ පිළිතුරු කිහිපයක් ඇත, අප අතර සිටින ගීක්කරුවන් සඳහා රසවත් තොරතුරු රාශියක් ලබා දෙයි, නමුත් එය ඇත්තෙන්ම තරමක් සරලයි - ෂෙල් ලූපයක විශාල ගොනුවක් සැකසීම ඉතා මන්දගාමී ය.

සාමාන්‍ය ආකාරයේ ෂෙල් ස්ක්‍රිප්ට් එකක ප්‍රශ්න කරන්නා සිත්ගන්නාසුළු යැයි මම සිතමි, එය සමහර විධාන රේඛා විග්‍රහ කිරීම, පරිසර සැකසුම, ලිපිගොනු සහ නාමාවලි පරීක්ෂා කිරීම සහ එහි ප්‍රධාන කාර්යයට පිවිසීමට පෙර තව ටිකක් ආරම්භ කිරීම සමඟ ආරම්භ විය හැකිය: විශාල හරහා ගමන් කිරීම රේඛීය-නැඹුරු පෙළ ගොනුව.

පළමු කොටස් සඳහා ( initialization), සාමාන්‍යයෙන් ෂෙල් විධාන මන්දගාමී වීම වැදගත් නොවේ - එය ක්‍රියාත්මක වන්නේ විධාන දුසිම් කිහිපයක් පමණි, සමහර විට කෙටි ලූප කිහිපයක් සමඟ ය. අප එම කොටස අකාර්යක්ෂම ලෙස ලිවුවද, සාමාන්‍යයෙන් ඒ සියල්ල ආරම්භ කිරීමට තත්පරයකට වඩා අඩු කාලයක් ගතවනු ඇත, එය හොඳයි - එය සිදුවන්නේ එක් වරක් පමණි.

නමුත් අපි රේඛා දහස් ගණනක් හෝ මිලියන ගණනක් ඇති විය හැකි මහා ගොනුව, සැකසීම සඳහා මත ලබා විට, එය නොවේ දඩ එක් එක් මාර්ගය සඳහා ෂෙල් තිර රචනය දෙවන සැලකිය යුතු භාගය ගැනීම සඳහා (එය දුසිම් මිලි තත්පර කිහිපයක් විතරයි පවා නම්), එය පැය ගණනක් එකතු කළ හැකි නිසා.

අපට වෙනත් මෙවලම් භාවිතා කිරීමට අවශ්‍ය වන්නේ එවිටය, යුනික්ස් ෂෙල් ස්ක්‍රිප්ට් වල සුන්දරත්වය නම් ඒවා අපට එය කිරීම පහසු කරයි.

සෑම පේළියක්ම බැලීමට ලූපයක් භාවිතා කරනවා වෙනුවට, අපට සම්පූර්ණ ගොනුව විධාන නල මාර්ගයක් හරහා යැවිය යුතුය . මෙයින් අදහස් කරන්නේ, විධාන දහස් ගණනක් හෝ මිලියන ගණනක් ඇමතීම වෙනුවට, කවචය ඒවා අමතන්නේ එක් වරක් පමණක් බවයි. එම විධානයන්ට ලිපිගොනු පේළිය සැකසීමට ලූප ඇති බව සත්‍යයකි, නමුත් ඒවා ෂෙල් ස්ක්‍රිප්ට් නොවන අතර ඒවා වේගවත් හා කාර්යක්ෂම ලෙස නිර්මාණය කර ඇත.

අපගේ නල මාර්ග තැනීම සඳහා භාවිතා කළ හැකි සරල සිට සංකීර්ණ දක්වා යුනික්ස් බොහෝ අපූරු මෙවලම් වලින් සමන්විතය. මම සාමාන්‍යයෙන් සරල ඒවා සමඟ ආරම්භ කරන අතර අවශ්‍ය විටදී වඩාත් සංකීර්ණ ඒවා පමණක් භාවිතා කරමි.

බොහෝ පද්ධතිවල ඇති සම්මත මෙවලම් සමඟ රැඳී සිටීමට මම උත්සාහ කරමි, එය සැමවිටම කළ නොහැකි වුවද මගේ භාවිතය අතේ ගෙන යා හැකි ලෙස තබා ගැනීමට උත්සාහ කරමි. ඔබේ ප්‍රියතම භාෂාව පයිතන් හෝ රූබි නම්, ඔබේ මෘදුකාංගය ක්‍රියාත්මක වීමට අවශ්‍ය සෑම වේදිකාවකම එය ස්ථාපනය කර ඇති බවට සහතික කර ගැනීමේ අමතර උත්සාහය ඔබට කමක් නැත :-)

සරල මෙවලම් head, tail, grep, sort, cut, tr, sed, join(2 ගොනු ඒකබද්ධ විට), සහ awkඑක්-ලයිනර් තවත් බොහෝ අය අතර. රටා ගැලපීම සහ sedවිධාන සමඟ සමහර අයට කළ හැකි දේ පුදුම සහගතය .

එය වඩාත් සංකීර්ණ වූ විට සහ ඔබ එක් එක් පේළියට යම් තර්කනයක් යෙදිය යුතු විට එය awkහොඳ විකල්පයකි - එක්-ලයිනර් එකක් (සමහර අය සම්පූර්ණ අමුතු ස්ක්‍රිප්ට් 'එක පේළියක' තබති, එය එතරම් කියවිය නොහැකි වුවද) හෝ අ කෙටි බාහිර පිටපත.

ලෙස awk(ඔබගේ ෂෙල් වැනි) විසින් අර්ථ දක්වනු භාෂාව වන අතර, එය රේඛීය-විසින්-රේඛාව හුඟක් කාර්යක්ෂමව සකසන කළ හැකි බව නියමයි, නමුත් එය මේ සඳහා අරමුණු-ඉදි වන අතර ඇත්තටම එය ඉතා වේගවත් ය.

පසුව තියෙනවා Perlහා පාඨ ගොනු, සැකසීම ඉතා හොඳ බව වෙනත් විධානාවලි භාෂාවන් විශාල සංඛ්යාවක්, සහ ප්රයෝජනවත් පුස්තකාල ගොඩක් එක්ක එන්න.

අවසාන වශයෙන්, ඔබට උපරිම වේගය සහ ඉහළ නම්යතාවයක් අවශ්‍ය නම් හොඳ පැරණි සී ඇත (පෙළ සැකසීම ටිකක් වෙහෙසකර වුවත්). නමුත් ඔබ හමුවන සෑම වෙනස් ගොනු සැකසුම් කාර්යයක් සඳහාම නව සී වැඩසටහනක් ලිවීම ඔබේ කාලය ඉතා නරක ලෙස භාවිතා කරයි. මම CSV ලිපිගොනු සමඟ වැඩ කරන අතර, විවිධ ව්‍යාපෘති වල නැවත භාවිතා කළ හැකි C හි සාමාන්‍ය උපයෝගිතා කිහිපයක් ලියා ඇත. ඇත්ත වශයෙන්ම, මෙය මගේ ෂෙල් ස්ක්‍රිප්ට් වලින් ඇමතිය හැකි 'සරල, වේගවත් යුනික්ස් මෙවලම්' පරාසය පුළුල් කරයි, එබැවින් මට බොහෝ ව්‍යාපෘති හැසිරවිය හැක්කේ ස්ක්‍රිප්ට් ලිවීමෙන් පමණි, එය සෑම විටම බෙස්පෝක් සී කේතය ලිවීමට හා නිදොස් කිරීමට වඩා වේගවත් වේ!

අවසාන ඉඟි කිහිපයක්:

  • ඔබගේ ප්‍රධාන ෂෙල් ස්ක්‍රිප්ට් එක සමඟ ආරම්භ කිරීමට අමතක නොකරන්න export LANG=C, නැතහොත් බොහෝ මෙවලම් ඔබගේ සරල-පැරණි-ASCII ගොනු යුනිකෝඩ් ලෙස සලකනු ඇත, එමඟින් ඒවා මන්දගාමී වේ
  • පරිසරය නොසලකා ස්ථාවර ඇණවුමක් නිෂ්පාදනය කිරීමට export LC_ALL=Cඔබට අවශ්‍ය නම් සැකසුමද සලකා බලන්න sort!
  • ඔබට sortඔබේ දත්ත අවශ්‍ය නම් , ඒ සියල්ලටම වඩා වැඩි කාලයක් (සහ සම්පත්: CPU, මතකය, තැටිය) ගතවනු ඇත, එබැවින් sortවිධාන ගණන සහ ඒවා වර්ග කරන ලිපිගොනු ප්‍රමාණය අවම කිරීමට උත්සාහ කරන්න
  • තනි නල මාර්ගයක්, හැකි විට සාමාන්‍යයෙන් වඩාත්ම කාර්යක්ෂම වේ - අතරමැදි ලිපිගොනු සමඟ අනුපිළිවෙලින් බහු නල මාර්ග ධාවනය කිරීම වඩාත් කියවිය හැකි සහ නිදොස්කරණය කළ හැකි නමුත් ඔබේ වැඩසටහනට ගතවන කාලය වැඩි කරයි

6
බොහෝ සරල මෙවලම්වල නල මාර්ග (විශේෂයෙන් සඳහන් කළ ඒවා, හිස, වලිගය, ග්‍රෙප්, වර්ග කිරීම, කැපීම, ට්‍රී, සෙඩ්, ...) බොහෝ විට අනවශ්‍ය ලෙස භාවිතා කරනු ලැබේ, විශේෂයෙන් ඔබට දැනටමත් එම නල මාර්ගයේ අමුතු අවස්ථාවක් තිබේ නම් එය කළ හැකිය. එම සරල මෙවලම්වල කාර්යයන් ද වේ. සලකා බැලිය යුතු තවත් කාරණයක් නම්, නල මාර්ගවල ඉදිරිපස පැත්තේ ඇති ක්‍රියාවලීන්ගෙන් පසුපස පැත්තේ දිස්වන ක්‍රියාවලීන් වෙත සරල හා විශ්වාසදායක ලෙස රාජ්‍ය තොරතුරු යැවිය නොහැකි වීමයි. සරල වැඩසටහන් වල නල මාර්ග සඳහා ඔබ භාවිතා කරන්නේ නම්, ඔබට තනි රාජ්‍ය ඉඩක් ඇත.
ජැනිස්

15

ඔව් නමුත්...

මෙම Stéphane Chazelas නිවැරදි පිළිතුර මත පදනම් වේ විශේෂිත ද්විමය ගොනු, වැනි සෑම පෙළ මෙහෙයුම පැවරීම සංකල්පය grep, awk, sedසහ වෙනත් අය.

ලෙස පහත වැටේ, තමා විසින් ගොඩක් දේවල් කිරීමේ හැකියාව ඇති හැඳි (පවා සියලු වැඩ කරන්නේ තවත් භාෂණ ධාවනය වඩා) වඩා ඉක්මනින් බවට පත් විය හැක.

නියැදිය සඳහා, මෙම ලිපිය බලන්න:

https://stackoverflow.com/a/38790442/1765658

හා

https://stackoverflow.com/a/7180078/1765658

පරීක්ෂා කර සංසන්දනය කරන්න ...

ඇත්ත වශයෙන්

පරිශීලක ආදානය සහ ආරක්ෂාව පිළිබඳ කිසිදු සැලකිල්ලක් නොමැත !

වෙබ් යෙදුම යටතේ ලියන්න එපා !!

නමුත් කොහෙද, සේවාදායකය පරිපාලනය කාර්යයන් සඳහා බොහෝ වෙනුවට භාවිතා කළ හැකි ඉතා කාර්යක්ෂම විය හැකි bash builtins භාවිතා.

මගේ තේරුම:

පද්ධති පරිපාලනයට වඩා බින් යුටිල්ස් වැනි මෙවලම් ලිවීම එකම ආකාරයේ කාර්යයක් නොවේ.

ඉතින් එකම මිනිසුන් නොවේ!

කොහෙද sysadmins දැන ගැනීමට ඇති shell, ඔවුන් ලිවීමට හැකි මූලාදර්ශවල ඔහුගේ prefered (සහ වඩාත් ප්රකට) මෙවලමක් භාවිතා.

මෙම නව උපයෝගීතාව (මූලාකෘති) සැබවින්ම ප්‍රයෝජනවත් නම්, තවත් සමහර පුද්ගලයින්ට තවත් සුදුසු භාෂාවක් භාවිතා කරමින් කැපවූ මෙවලමක් සංවර්ධනය කළ හැකිය.


1
හොඳ උදාහරණයක්. ඔබේ ප්‍රවේශය නිසැකවම ලොලොලක්ස් ක්‍රමයට වඩා කාර්යක්ෂම වේ, නමුත් ටෙන්සිබායිගේ පිළිතුර (මෙම IMO කිරීමට නිවැරදි ක්‍රමය, එනම් ෂෙල් ලූප භාවිතා නොකර) ඔබට වඩා වේගයෙන් ඇණවුම් කරන්නේ කෙසේදැයි බලන්න . නම් හා ඔබ ඔබේ ගොඩක් වේගවත් වේ නෑ භාවිතා bash. (මගේ පද්ධතියේ මගේ පරීක්ෂණයේදී ksh93 සමඟ 3 ගුණයකින් වේගවත්). bashසාමාන්‍යයෙන් මන්දගාමී කවචයයි. පවා zshඑම පිටපතෙහි දෙගුණයක් වේගවත් වේ. ඔබට නොකියවූ විචල්‍යයන් සහ භාවිතය පිළිබඳ ගැටළු කිහිපයක් ද තිබේ read. ඉතින් ඔබ ඇත්ත වශයෙන්ම මෙහි මගේ කරුණු බොහෝමයක් විදහා දක්වයි.
ස්ටෙෆාන් චසෙලාස්

1
මම එකඟ StéphaneChazelas @, bash බොහෝ විට මන්දගාමී වේ වේ ෂෙල් ජනතාව අද භාවිතා කළ හැකි, නමුත් ඉතාමත් පුළුල් ලෙස කෙසේ හෝ භාවිතා.
එෆ්. හවුරි

1
@Tensibai, ඔබට සම්බ වේ POSIXsh , Awk , sed , grep, ed, ex, cut, sort, join... බෑෂ් වඩා විශ්වසනීයත්වය සමග සියලු හෝ perl බසට ලං.
වයිල්ඩ්කාඩ්

1
& ටෙන්සිබායි, යූ ඇන්ඩ් එල් සම්බන්ධ සියලු පද්ධති, ඒවායින් බොහොමයක් (සොලාරිස්, ෆ්‍රීබීඑස්ඩී, එච්පී / යූඑක්ස්, ඒඅයිඑක්ස්, බොහෝ කාවැද්දූ ලිනක්ස් පද්ධති ...) bashපෙරනිමියෙන් ස්ථාපනය කර නැත. bashබොහෝ දුරට එකම ඇපල් macOS සහ GNU පද්ධති මත (මම මොකක්ද ඔබ කතා සිතමු හමු වී ඇත ප්රධාන බෙදාහැරීම් බොහෝ පද්ධති ද (වගේ විකල්ප පැකේජය ලෙස ඇති නමුත්,) zsh, tcl, python...)
Stéphane Chazelas

1
St ස්ටෙෆේන් හොඳයි, සිස්කෝ නෙක්සස්, බාෂ්, චෙක්පොයින්ට්, එෆ් 5, පරෙස්සම් වන්න, බ්ලූකෝට් ද භාවිතා කරයි (ඇත්ත වශයෙන්ම මම කාවැද්දූ පද්ධති ලෙස හඳුන්වන්නේ) මම ලිනක්ස් හි බෙදා හැරීම පරික්ෂා කර බැලුවෙමි, නමුත් මට මතක නැත එච්පී / යූඑක්ස් හෝ අයික්ස් බාෂ් නොමැතිව, අයික්ස් අනුකරණය පවා os400 තුළ මම එය දැන්වීමක් දැක ඇත්තෙමි. කෙසේ වෙතත්, කාරණය වූයේ 'පර්ල් වලට වඩා හොඳ අවස්ථාවක් ලබා ගැනීමට වඩා හොඳ අවස්ථාවක් තිබේ', ඔබ 'අතේ ගෙන යා හැකි' කේතය ලියන විට පොසික්ස් අනුකූලව සිටීම ප්‍රධාන ඉලක්කය විය යුතු බව මම සම්පූර්ණයෙන්ම එකඟ වෙමි.
ටෙන්සිබායි
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.