නල ආදාන පේළියකට එක් වරක් විධානයක් ක්‍රියාත්මක කරන්න?


178

සෑම තරඟයක් සඳහාම වරක් ජාවා විධානයක් ක්‍රියාත්මක කිරීමට මට අවශ්‍යය ls | grep pattern -. මෙම අවස්ථාවේ දී, මට කළ හැකි යැයි මම සිතමි, find pattern -exec java MyProg '{}' \;නමුත් සාමාන්‍ය කාරණය ගැන මට කුතුහලයක් ඇත - “සම්මත ආදානයේ සෑම පේළියකටම වරක් විධානයක් ක්‍රියාත්මක කරන්න” යැයි පැවසීමට පහසු ක්‍රමයක් තිබේද? (මාළු හෝ බෑෂ් වලින්.)

Answers:


101

ඒක තමයි xargsකරන්නේ.

... | xargs command

33
තරමක් නොවේ. printf "foo bar\nbaz bat" | xargs echo wheeලැබෙනු ඇත whee foo bar baz bat. සමහර විට -Lහෝ -nවිකල්ප එකතු කළ හැකිද?
ජැන්ඩර්

4
And ජැන්ඩර් ප්‍රශ්නය තරමක් සාමාන්‍ය නිසා මම සාමාන්‍ය මෙවලම දුන්නා. නිශ්චිත තත්වයන් මත පදනම්ව ඔබට එහි හැසිරීම විකල්ප සමඟ සකස් කිරීමට සිදුවන බව ඇත්ත.
කීත්

4
... | tr '\ n' '\ 0' | xargs -0
vrdhn

11
වැනි, "ප්‍රශ්නයට නිවැරදි පිළිතුර ලබා දෙන විශේෂිත තත්වයන්". :)
mattdm

10
Xargs සමඟ මෙය කිරීමට සුදුසුම ක්‍රමය ඔබට දැකීමට අවශ්‍ය නම්, මගේ පිළිතුර පහත බලන්න.
මයිකල් ගෝල්ඩ්ස්ටයින්

196

පිළිගත් පිළිතුරට නිවැරදි අදහසක් ඇත, නමුත් ප්‍රධාන දෙය xargsනම් -n1ස්විචය සම්මත කිරීමයි , එයින් අදහස් වන්නේ "ප්‍රතිදාන රේඛාවකට එක් වරක් විධානය ක්‍රියාත්මක කරන්න:"

cat file... | xargs -n1 command

නැතහොත්, තනි ආදාන ගොනුවක් සඳහා ඔබට නළය catසම්පූර්ණයෙන්ම වළක්වා ගත හැකි අතර :

<file xargs -n1 command

2
ද පොලී ඇති හැකියාව වේ xargsකිරීමට නොහැකි නම්, ක්රියාත්මක stdinහිස්: --no-run-if-empty -r: සම්මත ආදාන ඕනෑම nonblanks අඩංගු නොවේ නම්, මෙම විධානය ක්රියාත්මක කරන්න එපා. සාමාන්‍යයෙන්, ආදානය නොමැති වුවද විධානය වරක් ක්‍රියාත්මක වේ. මෙම විකල්පය GNU දිගුවකි.
රොනාන් ජුචෙට්

9
ඇතුළත රේඛාවට ඔබ පිවිසෙන්නේ කෙසේද command?
බීටී

Xargs හි නිවැරදි භාවිතය මෙයයි. -N1 නොමැතිව, එය ක්‍රියාත්මක වන්නේ පරාමිති ලැයිස්තුවක් බහු ආයාචනා ලෙස සලකන විධාන මත පමණි.
මාස්ටර්සිලෝ

4
printf "foo bar \ nbaz bat" | xargs -n1 echo whee බෙදී යන්නේ වචන වලින් මිස රේඛාවලින් නොවේ
Gismo Ranas

118

Bash හෝ වෙනත් බෝර්න් විලාසිතාවේ කවචයක (අළු, ksh, zsh,…):

while read -r line; do command "$line"; done

read -rසම්මත ආදානයෙන් තනි පේළියක් කියවයි ( බැක්ස්ලෑෂ් අර්ථ නිරූපණය readනොකර -r, ඔබට එය අවශ්‍ය නැත). මේ අනුව ඔබට පහත සඳහන් දෑ වලින් එකක් කළ හැකිය:

$ command | while read -r line; do command "$line"; done  

$ while read -r line; do command "$line"; done <file

7
මම උත්සාහ කළ විට tail -f syslog | grep -e something -e somethingelse| while read line; do echo $line; doneඑය සාර්ථක වූයේ නැත. එය whileලූපයක් තුළට ලූපයක් තුළට වැඩ කර, හුදෙක් සමඟ වැඩ කර, යුක්තිසහගත ලෙස ක්‍රියා tail -fකළ grepනමුත් පයිප්ප දෙකම සමඟ නොවේ. ලබා දෙන, grepමේ --line-bufferedවිකල්පය එය වැඩ කරන

සෑම පේළියක්ම stdin වෙත යැවිය යුතු විටද මෙය ක්‍රියාත්මක වේ:command | while read -r line; do echo "$line" | command ; done
Den

22

මම කීත් සමඟ එකඟ වෙමි, xargs යනු කාර්යය සඳහා වඩාත් පොදු මෙවලමයි.

මම සාමාන්‍යයෙන් පියවර 3 ක ප්‍රවේශයක් භාවිතා කරමි.

  • ඔබ සමඟ වැඩ කිරීමට කැමති දෙයක් ලැබෙන තුරු මූලික දේවල් කරන්න
  • නිවැරදි වාක්‍ය ඛණ්ඩය ලබා ගන්නා පරිදි පේළිය අමුතු ලෙස සකස් කරන්න
  • xargs විසින් එය ක්‍රියාත්මක කිරීමට ඉඩ දෙන්න, සමහර විට bash ආධාරයෙන්.

කුඩා හා වේගවත් ක්‍රම තිබේ, නමුත් මෙම ක්‍රම සෑම විටම පාහේ ක්‍රියාත්මක වේ.

සරල උදාහරණයක්:

ls | 
grep xls | 
awk '{print "MyJavaProg --arg1 42 --arg2 "$1"\0"}' | 
xargs -0 bash -c

පළමු පේළි 2 සමඟ වැඩ කිරීම සඳහා සමහර ලිපිගොනු තෝරා ගනී, පසුව awk ක්‍රියාත්මක කිරීමට විධානයක් සහිත ලස්සන නූලක් සකස් කරයි. සමහර තර්ක සහ $ 1 යනු පයිප්පයේ පළමු තීරු ආදානයයි. අවසාන වශයෙන් මම xargs විසින් මෙම නූල යවන ලෙසට වග බලා ගන්නෙමි.

එය ටිකක් වැඩිපුර මරණයක්, නමුත් මෙම වට්ටෝරුව ඉතා නම්‍යශීලී බැවින් බොහෝ ස්ථානවල මට උදව් කර ඇත.


6
සටහන, xargs -0ශුන්‍ය බයිට් පටිගත කිරීමේ බෙදුම්කරුවෙකු ලෙස භාවිතා කරයි, එබැවින් ඔබේ අමුතු මුද්‍රණ ප්‍රකාශය විය යුතුයprintf("MyJavaProg --args \"%s\"\0",$1)
ග්ලෙන් ජැක්මන්

ඇග්ලන්: ශුන්‍ය වර්‍ගය මඟ හැරී ඇත, පිළිතුර යාවත්කාලීන කරනු ඇත
ජොහාන්

@ ජොහාන් ලොකු දෙයක් නොවේ, නමුත් ඔබ භාවිතා කරන්නේ නම් ඔබට awkඑය රටා ගැලපීම හා grep උදා. මඟ හැරිය හැක ,ls | awk '/xls/ {print...
එරික් රෙනූෆ්

15

GNU සමාන්තරය එවැනි කාර්යයන් සඳහා සාදා ඇත. සරලම භාවිතය:

cat stuff | grep pattern | parallel java MyProg

වැඩිදුර දැනගැනීම සඳහා හඳුන්වාදීමේ වීඩියෝව නරඹන්න: http://www.youtube.com/watch?v=OpaiGYxkSuQ


2
ගොනුව කෙලින්ම කියවිය හැකි catබැවින් මෙහි සැබෑ අවශ්‍යතාවයක් නොමැතgrep
එරික් රෙනූෆ්


1
සබැඳියට ස්තූතියි, එය කියවීම පහසු බව මම අනිවාර්යයෙන්ම එකඟ නොවෙමි, නමුත් එය නොසලකා සලකා බැලූ බව දැන ගැනීම සතුටක්. විකල්පය සැබවින්ම නොවන < stuff grep patternනමුත් grep pattern stuffනැවත හරවා යැවීමක් හෝ බළලෙකු අවශ්‍ය නොවන බැවින් සබැඳිය ඇත්ත වශයෙන්ම මෙහි අදාළ නොවන බව මම දැන් තරයේ විශ්වාස කරමි . කෙසේ වෙතත්, එය ඔබේ තර්කය ද්‍රව්‍යමය වශයෙන් වෙනස් නොකරන අතර සෑම විටම ආරම්භ වන පයිප්පයක දේවල් භාවිතා කිරීම වඩාත් පැහැදිලි යැයි ඔබ සිතන්නේ නම් cat, එවිට ඔබට බලය ලබා දෙන්න
එරික් රෙනූෆ්

10

එසේම, while readමාළු කවචයේ ඇති ලූපය ( ටැගය භාවිතා කළ බව සලකමින් ඔබට මාළු කවචය අවශ්‍ය යැයි මම සිතමි ).

command | while read line
    command $line
end

සැලකිල්ලට ගත යුතු කරුණු කිහිපයක්.

  • read-rබහුලව භාවිතා වන අවස්ථාව පහසු කිරීම සඳහා තර්කයක් නොගන්නා අතර එය ඔබගේ පසුපසට අර්ථ නිරූපණය නොකරයි.
  • ඔබට උපුටා දැක්වීමට අවශ්‍ය නැත $line, බාෂ් මෙන් නොව මාළු අවකාශයන් අනුව විචල්‍යයන් වෙන් නොකරයි.
  • commandඑය සින්ටැක්ස් දෝෂයකි (ස්ථාන දරණ තර්ක භාවිතා කිරීම අල්ලා ගැනීම සඳහා). නියම විධානය සමඟ එය ප්රතිස්ථාපනය කරන්න.

1
නැත whileසමග යුගල කළ යුතු doසහ doneවෙනුවට end?
aff

@aff මෙය විශේෂයෙන් විවිධ වාක්‍ය ඛණ්ඩ ඇති මාළු කවච ගැන ය.
කොන්රාඩ් බොරොව්ස්කි

ආහ්, මේ අපි ඒ දේ මාළු මාධ්යයක්.
aff

10

ඔබේ විධාන රේඛාවට ආදාන තර්කය හරියටම ඇතුළත් කර ඇති ස්ථානය පාලනය කිරීමට ඔබට අවශ්‍ය නම් හෝ ඔබට එය කිහිප වතාවක් පුනරාවර්තනය කිරීමට අවශ්‍ය නම් ඔබට භාවිතා කළ හැකිය xargs -I{}.

උදාහරණ # 1

another_folderවත්මන් නාමාවලියෙහි උප ෆෝල්ඩර පිළිබිඹු කරන හිස් ෆෝල්ඩර ව්‍යුහයක් සාදන්න :

    ls -1d ./*/ | xargs -I{} mkdir another_folder/{}
උදාහරණ # 2

Stdin වෙතින් එන ගොනු ලැයිස්තුවක මෙහෙයුමක් යොදන්න, මේ අවස්ථාවේ .htmlදී .bakදිගුවක් එකතු කිරීමෙන් එක් එක් ගොනුවේ පිටපතක් සාදන්න :

    find . -iname "*.html" | xargs -I{} cp {} {}.bak

සිට xargsMacOS / BSD සඳහා man පිටුව :

 -I replstr
         Execute utility for each input line, replacing one or more occurrences of
         replstr in up to replacements (or 5 if no -R flag is specified) arguments
         to utility with the entire line of input.  The resulting arguments, after
         replacement is done, will not be allowed to grow beyond 255 bytes; this is
         implemented by concatenating as much of the argument containing replstr as
         possible, to the constructed arguments to utility, up to 255 bytes.  The
         255 byte limit does not apply to arguments to utility which do not contain
         replstr, and furthermore, no replacement will be done on utility itself.
         Implies -x.

ලිනක්ස් xargsමෑන් පිටුව :

   -I replace-str
          Replace  occurrences of replace-str in the initial-
          arguments with names read from standard input.  Al
          so,  unquoted  blanks do not terminate input items;
          instead the separator  is  the  newline  character.
          Implies -x and -L 1.

1

සනීපාරක්ෂක නොවන යෙදවුම් සමඟ කටයුතු කරන විට, මම එය ක්‍රියාත්මක කිරීමට පෙර දෘශ්‍ය පරීක්ෂාව සඳහා මුළු කාර්යයම 'අක්ෂර වින්‍යාසය' ලෙස දැකීමට කැමතියි (විශේෂයෙන් එය මිනිසුන්ගේ තැපැල් පෙට්ටිය පිරිසිදු කිරීම වැනි විනාශකාරී දෙයක් වන විට).

ඉතින් මම කරන්නේ පරාමිති ලැයිස්තුවක් ජනනය කිරීමයි (එනම් පරිශීලක නාම), එය එක් ගොනුවකට එක්-වාර්තා-රේඛීය ආකාරයෙන් ගොනුවකට පෝෂණය කරන්න:

johndoe  
jamessmith  
janebrown  

ඉන්පසුව මම ලැයිස්තුව විවෘත කර vimඑය සෙවුම් සමඟ සම්බන්ධ කර ප්‍රකාශන ප්‍රතිස්ථාපනය කර ක්‍රියාත්මක කිරීමට අවශ්‍ය සම්පූර්ණ විධාන ලැයිස්තුවක් ලබා ගන්නා තෙක්:

/bin/rm -fr /home/johndoe  
/bin/rm -fr /home/jamessmith 

මේ ආකාරයෙන් ඔබේ රීජෙක්ස් අසම්පූර්ණ නම්, විභව ගැටළු ඇතිවිය හැකි විධානය කුමක්දැයි ඔබට පෙනෙනු ඇත (එනම්. /bin/rm -fr johnnyo connor). මේ ආකාරයෙන් ඔබට ඔබේ රීජෙක්ස් අහෝසි කළ හැකි අතර, වඩාත් විශ්වාසදායක අනුවාදයක් සමඟ එය නැවත උත්සාහ කරන්න. නම මැන්ග්ලිං මේ සඳහා කුප්‍රකට ය, මන්ද වැන් ගොග්, ඕ'කොනර්ස්, ශාන්ත ක්ලෙයාර්, ස්මිත්-වෙස්සන් වැනි සියලු අද්දර සිද්ධීන් ගැන සැලකිලිමත් වීම දුෂ්කර ය.

ඇති set hlsearchමේ දේ සඳහා ප්රයෝජනවත් වේ vimඑය නොගැලපේ නම්, ඔබ පහසුවෙන් සොයාගත හැකි නිසා එය සියලු තරග ඉස්මතු හෝ අනපේක්ෂිත ආකාරයෙන් තරග කරනු ඇත ලෙස.

ඔබේ රීජෙක්ස් පරිපූර්ණ වූ පසු එය ඔබට පරීක්ෂා කිරීමට / සිතිය හැකි සියලු අවස්ථාවන් හසු කර ගත් පසු, මම සාමාන්‍යයෙන් එය සෙඩ් ප්‍රකාශනයක් බවට පරිවර්තනය කරමි, එවිට එය වෙනත් ධාවනයකට සම්පූර්ණයෙන්ම ස්වයංක්‍රීය කළ හැකිය.

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


1

මෙන්න, ඔබට වහාම භාවිතා කළ හැකි පිටපත් පිටපතක්:

cat list.txt | xargs -I{} command parameter {} parameter

ලැයිස්තුවේ ඇති අයිතමය {} ඇති තැනට දමනු ලබන අතර ඉතිරි විධානය සහ පරාමිතීන් පවතින ආකාරයටම භාවිතා වේ.


0

වැඩසටහනක් නළය නොසලකා හැර ගොනු තර්ක ලෙස පිළිගන්නේ නම්, ඔබට එය විශේෂ ගොනුවට යොමු කළ හැකිය /dev/stdin.

මම ජාවා ගැන හුරුපුරුදු නැත, නමුත් ඔබ එය බාෂ් සඳහා කරන්නේ කෙසේද යන්න පිළිබඳ උදාහරණයක් මෙහි දැක්වේ:

$ echo $'pwd \n cd / \n pwd' |bash /dev/stdin
/home/rolf
/

\nනව රේඛාවලට පරිවර්තනය කිරීම සඳහා bash අවශ්‍ය වේ . ඒ ඇයි දැයි මට විශ්වාස නැත.



0

xargsවෙනත් පිළිතුරු වලින් දැක්වෙන පරිදි මෙය කළ හැකිය . ප්‍රශ්නයේ "එක් පේළියකට වරක්" කොටසෙහි විශේෂතා දෙකක් වෙන්කර හඳුනාගත යුතුය:

  1. වරක්: භාවිතා කරන්න -n 1, මෙය එක් එක් තර්කය සඳහා හරියටම එක් වරක් විධානය ක්‍රියාත්මක කරන බව සහතික කරයි. කෙසේ වෙතත්, පෙරනිමියෙන්, xargsතර්ක අවකාශයෙන් වෙන් කර ඇති බව උපකල්පනය කරයි - ලිපිගොනු වල හිස් තැන් ඇති විට මෙය කැඩී යයි.
  2. එක් පේළියකට: -d '\n'ආදානය tr '\n' '\0'භාවිතා කර පෙර සැකසුම් කරන්න -0. මෙය ආදානයේ අවකාශයන්ට එරෙහිව විධානය ශක්තිමත් කරයි.

අවසාන විධාන රේඛාව පසුව:

.... | xargs -n 1 -d '\n' <command>

හෝ (සමඟ tr)

.... | tr '\n' '\0' | xargs -n 1 -0 <command>

ඔබේ විධානයට එකවර බහුවිධ තර්ක සැකසිය හැකි නම් (වැනි grepහෝ වැනි sed), -n 1බොහෝ අවස්ථාවන්හි ක්‍රියාකාරිත්වය වේගවත් කිරීම සඳහා ඔබට මඟ හැරිය හැක .

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.