बहु-पंक्ति बयानों को एक-पंक्ति कमांड-लाइन में निष्पादित करना?


197

मैं -cएक-लाइनर लूप को निष्पादित करने के लिए अजगर का उपयोग कर रहा हूं , अर्थात:

$ python -c "for r in range(10): print 'rob'"

यह ठीक काम करता है। हालाँकि, यदि मैं लूप के लिए मॉड्यूल आयात करता हूं, तो मुझे एक सिंटैक्स त्रुटि मिलती है:

$ python -c "import sys; for r in range(10): print 'rob'"
  File "<string>", line 1
    import sys; for r in range(10): print 'rob'
              ^
SyntaxError: invalid syntax

किसी भी विचार यह कैसे तय किया जा सकता है?

मेरे लिए यह महत्वपूर्ण है कि मैं इसे वन-लाइनर के रूप में रखूं ताकि मैं इसे मेकफाइल में शामिल कर सकूं।


क्या इससे आपके सवाल का जवाब मिलता है? शब्दकोश का उपयोग करने के लिए फ़ंक्शन का चयन करने के लिए
pfabri

जवाबों:


182

तुम यह कर सकते थे

echo -e "import sys\nfor r in range(10): print 'rob'" | python

या डब्ल्यू / आउट पाइप:

python -c "exec(\"import sys\nfor r in range(10): print 'rob'\")"

या

(echo "import sys" ; echo "for r in range(10): print 'rob'") | python

या @ साइलेंटगॉस्ट का जवाब / @ क्रस्ट का जवाब


अंतिम विकल्प विंडोज में python3 के साथ बहुत अच्छा काम करता है
इयान एलिस

1
@RudolfOlah उम्मीद है कि आप इसे अब तक जानते हैं, लेकिन सिर्फ संदर्भ के लिए, आपको python3 + के लिए प्रिंट स्टेटमेंट को लपेटने की आवश्यकता है जैसे:python -c "exec(\"import sys\nfor r in range(10): print('rob')\")"
systrigger

@ सिस्टीगर धन्यवाद, मुझे याद आया कि मुझे लगता है कि मैं एक भीड़ में था और एहसास नहीं था कि हे

89

इस शैली का उपयोग मेकफाइल्स में भी किया जा सकता है (और वास्तव में इसका उपयोग अक्सर किया जाता है)।

python - <<EOF
import sys
for r in range(3): print 'rob'
EOF

या

python - <<-EOF
    import sys
    for r in range(3): print 'rob'
EOF

बाद के मामले में प्रमुख टैब वर्ण भी हटा दिए जाते हैं (और कुछ संरचित दृष्टिकोण प्राप्त किया जा सकता है)

ईओएफ के बजाय किसी भी मार्कर शब्द को एक लाइन की शुरुआत में यहां दस्तावेज़ में दिखाई नहीं दे सकता है (यह भी देखें कि बैश मैनपेज में दस्तावेज यहां हैं या नहीं )।


9
अच्छा लगा। तर्कों को पारित करने के लिए , बस उन्हें बाद में रखें <<EOF। ध्यान दें, हालांकि, परिसीमनकर्ता को उद्धृत करना बेहतर है - उदाहरण के लिए, <<'EOF'ताकि यहां-दस्तावेज़ की सामग्री को अप-फ्रंट शेल विस्तार से बचाया जा सके ।
mklement0

56

मुद्दा वास्तव में आयात विवरण के साथ नहीं है, यह लूप के लिए कुछ भी होने से पहले है। या अधिक विशेष रूप से, एक अंतर्निर्मित ब्लॉक से पहले दिखाई देने वाली कुछ भी।

उदाहरण के लिए, ये सभी कार्य:

python -c "import sys; print 'rob'"
python -c "import sys; sys.stdout.write('rob\n')"

यदि आयात किया जा रहा है एक बयान एक मुद्दा था, यह काम करेगा, लेकिन यह नहीं है:

python -c "__import__('sys'); for r in range(10): print 'rob'"

अपने बहुत ही बुनियादी उदाहरण के लिए, आप इसे इस रूप में फिर से लिख सकते हैं:

python -c "import sys; map(lambda x: sys.stdout.write('rob%d\n' % x), range(10))"

हालाँकि, लैम्ब्डा केवल अभिव्यक्तियों को निष्पादित कर सकता है, न कि कथन या कई कथन, इसलिए आप अभी भी उस चीज़ को करने में असमर्थ हो सकते हैं जो आप करना चाहते हैं। हालाँकि, जेनरेटर एक्सप्रेशन, लिस्ट कॉम्प्रिहेंशन, लैम्ब्डा, sys.stdout.write, "मैप" बिलिन और कुछ क्रिएटिव स्ट्रिंग इंटरपोलेशन के बीच, आप कुछ शक्तिशाली वन-लाइनर्स कर सकते हैं।

सवाल यह है कि आप कितनी दूर जाना चाहते हैं, और किस बिंदु पर एक छोटी .pyफाइल लिखना बेहतर नहीं है, जिसे आपका मेफाइल इसके बजाय निष्पादित करता है?


31


- इस उत्तर को पायथन 3.x के साथ भी काम करने के लिए , printएक फ़ंक्शन के रूप में कहा जाता है : 3.x में, केवल print('foo') काम करता है, जबकि 2.x भी स्वीकार करता है print 'foo'
- एक क्रॉस-प्लेटफ़ॉर्म परिप्रेक्ष्य के लिए जिसमें विंडोज शामिल है , kxr का सहायक उत्तर देखें

में bash, kshयाzsh :

एक ANSI C- उद्धृत स्ट्रिंग ( $'...') का उपयोग \nकरें , जो स्ट्रिंग में पास होने से पहले वास्तविक newlines के लिए विस्तारित किए गए नए समाचारों का प्रतिनिधित्व करने की अनुमति देता है python:

python -c $'import sys\nfor r in range(10): print("rob")'

लाइन ब्रेक को प्रभावित करने के लिए कथनों और कथनों के \nबीच में नोट करें ।importfor

इस तरह के कमांड को शेल-वैरिएबल मान पास करने के लिए , पाइथन स्क्रिप्ट के अंदर तर्कों का उपयोग करना और उन्हें एक्सेस करना सबसे सुरक्षित है sys.argv:

name='rob' # value to pass to the Python script
python -c $'import sys\nfor r in range(10): print(sys.argv[1])' "$name"

एम्बेडेड शेल-वैरिएबल संदर्भों के साथ (एग्जिट सीक्वेंस-प्रीप्रोसेड) डबल-कोटेड कमांड स्ट्रिंग का उपयोग करने के पेशेवरों और विपक्षों की चर्चा के लिए नीचे देखें ।

$'...'तार के साथ सुरक्षित रूप से काम करने के लिए :

  • \अपने मूल स्रोत कोड में दोहरे उदाहरण ।
    • \<char>दृश्यों - जैसे \nइस मामले में, लेकिन यह भी इस तरह के रूप में हमेशा की तरह संदिग्ध \t, \r, \b- द्वारा विस्तारित किया जाता है $'...'(देखें man printfसमर्थित पलायन के लिए)
  • 'उदाहरण के रूप में बच \'

यदि आपको POSIX- अनुरूप रहना चाहिए :

printfएक कमांड प्रतिस्थापन के साथ प्रयोग करें :

python -c "$(printf %b 'import sys\nfor r in range(10): print("rob")')"

इस प्रकार के स्ट्रिंग के साथ सुरक्षित रूप से काम करने के लिए:

  • \अपने मूल स्रोत कोड में दोहरे उदाहरण ।
    • \<char>दृश्यों - जैसे \nइस मामले में, लेकिन यह भी सामान्य संदिग्धों जैसे \t, \r, \b- द्वारा विस्तारित किया जाता है printf(देखें man printfसमर्थित भागने दृश्यों के लिए)।
  • एक एकल-उद्धृत स्ट्रिंग पास करें printf %bऔर ( एकल '\'' ) के रूप में एम्बेडेड एकल उद्धरण से बचें

    • सिंगल कोट्स का उपयोग स्ट्रिंग की सामग्री को शेल द्वारा व्याख्या से बचाता है ।

      • कहा जाता है कि, लघु पायथन लिपियों के लिए (जैसा कि इस मामले में) आप अपनी स्क्रिप्ट्स में शेल चर मानों को शामिल करने के लिए एक दोहरे-उद्धृत स्ट्रिंग का उपयोग कर सकते हैं - जब तक कि आप संबद्ध नुकसानों से अवगत हैं (अगला बिंदु देखें); उदाहरण के लिए, शेल $HOMEवर्तमान उपयोगकर्ता के होम डायर तक फैलता है। निम्नलिखित कमांड में:

        • python -c "$(printf %b "import sys\nfor r in range(10): print('rob is $HOME')")"
      • हालांकि, आम तौर पर पसंदीदा दृष्टिकोण है कि तर्क के माध्यम से शेल से मूल्यों को पारित किया जाए , और sys.argvपायथन के माध्यम से उन तक पहुंच बनाई जाए; उपरोक्त आदेश के समतुल्य है:

        • python -c "$(printf %b 'import sys\nfor r in range(10): print("rob is " + sys.argv[1])')" "$HOME"
    • जबकि एक का उपयोग कर डबल-कोटेड स्ट्रिंग अधिक है सुविधाजनक यह आप एकल उद्धरण एम्बेडेड नहीं छोड़ा जाएगा और एम्बेडेड दोहरे उद्धरण चिह्नों के रूप में उपयोग करने के लिए अनुमति देता है - \"- यह भी द्वारा व्याख्या के लिए स्ट्रिंग विषय बना देता है खोल , जो या आशय नहीं हो सकता है हो सकता है; $और `आपके स्रोत कोड के अक्षर जो शेल के लिए नहीं हैं, सिंटैक्स त्रुटि का कारण हो सकता है या स्ट्रिंग को अनपेक्षित रूप से बदल सकता है।

      • इसके अतिरिक्त, \डबल-उद्धृत स्ट्रिंग्स में शेल का अपना प्रसंस्करण रास्ते में मिल सकता है; उदाहरण के लिए, पायथन को शाब्दिक आउटपुट प्राप्त करने के लिए ro\b, आपको इसे पास ro\\bकरना होगा; एक साथ '...'खोल स्ट्रिंग और दोगुनी \ उदाहरणों, हम पाते हैं:
        python -c "$(printf %b 'import sys\nprint("ro\\\\bs")')" # ok: 'ro\bs'
        इसके विपरीत, यह करता है नहीं काम के रूप में एक साथ इरादा "..."खोल स्ट्रिंग:
        python -c "$(printf %b "import sys\nprint('ro\\\\bs')")" # !! INCORRECT: 'rs'
        खोल व्याख्या दोनों "\b" और "\\b"शाब्दिक रूप में \b, अतिरिक्त का एक चकित संख्या की आवश्यकता होती है \वांछित प्रभाव को प्राप्त करने उदाहरणों:
        python -c "$(printf %b "import sys\nprint('ro\\\\\\\\bs')")"

के बजाय के माध्यम से कोड पारितstdin करने के लिए-c :

नोट: मैं यहाँ सिंगल- लाइन समाधान पर ध्यान केंद्रित कर रहा हूँ ; जोरो का जवाब दिखाता है कि यहां एक बहु-रेखा का उपयोग कैसे किया जाता है - हालांकि, परिसीमनकर्ता को उद्धृत करना सुनिश्चित करें ; उदाहरण के लिए, <<'EOF'जब तक कि आप स्पष्ट रूप से सामने वाले को स्ट्रिंग का विस्तार करने के लिए नहीं चाहते हैं (जो ऊपर उल्लिखित केवेट्स के साथ आता है)।


में bash, kshयाzsh :

एएनएसआई सी-उद्धृत स्ट्रिंग ( $'...') को यहां-स्ट्रिंग ( <<<...) के साथ मिलाएं :

python - <<<$'import sys\nfor r in range(10): print("rob")'

-pythonस्टड से पढ़ने के लिए स्पष्ट रूप से बताता है (जो यह डिफ़ॉल्ट रूप से करता है)। -इस मामले में वैकल्पिक है, लेकिन यदि आप भी स्क्रिप्ट के लिए तर्क पारित करना चाहते हैं, तो आपको स्क्रिप्ट फ़ाइल नाम से तर्क को अस्वीकार करने की आवश्यकता है:

python - 'rob' <<<$'import sys\nfor r in range(10): print(sys.argv[1])'

यदि आपको POSIX- अनुरूप रहना चाहिए :

printfउपरोक्त के रूप में उपयोग करें , लेकिन एक पाइपलाइन के साथ ताकि स्टड के माध्यम से इसका उत्पादन पारित किया जा सके:

printf %b 'import sys\nfor r in range(10): print("rob")' | python

एक तर्क के साथ:

printf %b 'import sys\nfor r in range(10): print(sys.argv[1])' | python - 'rob'

2
यह निर्वाचित उत्तर होना चाहिए!
पहली

1
यह भी काम करता है और शायद सबसे अच्छा जवाब है क्योंकि इसमें पूर्ण विवरण, ब्रावो शामिल हैं!

22

किसी भी विचार यह कैसे तय किया जा सकता है?

आपकी समस्या इस तथ्य से बनती है कि पाइथन के बयान, द्वारा अलग किए गए ;, केवल "छोटे बयान" होने की अनुमति है, जो सभी एक-लाइनर हैं। पायथन डॉक्स में व्याकरण फ़ाइल से :

stmt: simple_stmt | compound_stmt
simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
             import_stmt | global_stmt | nonlocal_stmt | assert_stmt)

अर्धविराम के माध्यम से अन्य बयानों के साथ कंपाउंड स्टेटमेंट को एक ही लाइन पर शामिल नहीं किया जा सकता है - इसलिए -cध्वज के साथ ऐसा करना बहुत असुविधाजनक हो जाता है।

बैश शेल वातावरण में रहते हुए पायथन का प्रदर्शन करते समय, मुझे यौगिक कथनों को शामिल करना बहुत उपयोगी लगता है। इस मज़बूती से करने का एकमात्र सरल तरीका heredocs (एक पॉज़िक्स शेल चीज़) के साथ है।

Heredocs

एक का प्रयोग करें हियरडॉक (के साथ बनाया <<) और अजगर के कमांड लाइन इंटरफेस विकल्प , -:

$ python - <<-"EOF"
        import sys                    # 1 tab indent
        for r in range(10):           # 1 tab indent
            print('rob')              # 1 tab indent and 4 spaces
EOF

-आफ्टर <<( <<-) जोड़ने से आप इंडेंट करने के लिए टैब का उपयोग कर सकते हैं (Stackoverflow टैब्स को स्पेस में कनवर्ट करता है, इसलिए मैंने इस पर जोर देने के लिए 8 स्पेस को इंडेंट किया है)। अग्रणी टैब छीन लिए जाएंगे।

आप इसे टैब के बिना भी कर सकते हैं <<:

$ python - << "EOF"
import sys
for r in range(10):
    print('rob')
EOF

चारों ओर उद्धरण EOFडालना पैरामीटर और अंकगणितीय विस्तार को रोकता है । यह वंशानुगत को और अधिक मजबूत बनाता है।

बैश बहु लीन तार

यदि आप दोहरे उद्धरण चिह्नों का उपयोग करते हैं, तो आपको शेल-विस्तार मिलेगा:

$ python -c "
> import sys
> for p in '$PATH'.split(':'):
>     print(p)
> "
/usr/sbin
/usr/bin
/sbin
/bin
...

शेल विस्तार से बचने के लिए एकल-उद्धरण का उपयोग करें:

$ python -c '
> import sys
> for p in "$PATH".split(":"):
>     print(p)
> '
$PATH

ध्यान दें कि हमें पायथन में शाब्दिक रूप से उद्धरण वर्णों को स्वैप करने की आवश्यकता है - हम मूल रूप से BASH द्वारा व्याख्या किए जा रहे उद्धरण वर्ण का उपयोग नहीं कर सकते हैं। हम उन्हें वैकल्पिक कर सकते हैं, जैसे कि हम पाइथन में कर सकते हैं - लेकिन यह पहले से ही काफी भ्रामक लग रहा है, यही कारण है कि मैं इसकी सिफारिश नहीं करता हूं:

$ python -c '
import sys
for p in "'"$PATH"'".split(":"):
    print(p)
'
/usr/sbin
/usr/bin
/sbin
/bin
...

स्वीकृत उत्तर की आलोचना (और अन्य)

यह बहुत पठनीय नहीं है:

echo -e "import sys\nfor r in range(10): print 'rob'" | python

बहुत पठनीय नहीं है, और इसके अतिरिक्त एक त्रुटि के मामले में डिबग करना मुश्किल है:

python -c "exec(\"import sys\\nfor r in range(10): print 'rob'\")"

शायद थोड़ा अधिक पठनीय, लेकिन अभी भी काफी बदसूरत है:

(echo "import sys" ; echo "for r in range(10): print 'rob'") | python

यदि आपके पास "अपने अजगर में है, तो आपके पास एक बुरा समय होगा :

$ python -c "import sys
> for r in range(10): print 'rob'"

गालियों mapको प्राप्त करने के लिए दुरुपयोग या सूची की समझ न रखें :

python -c "import sys; map(lambda x: sys.stdout.write('rob%d\n' % x), range(10))"

ये सभी दुखी और बुरे हैं। उन्हें मत करो।


3
व्याकरण की जानकारी के लिए ++; (गैर-विस्तार) यहाँ-डॉक्टर आसान है और सबसे मजबूत समाधान है, लेकिन स्पष्ट रूप से एक-लाइनर नहीं है। यदि एक एकल-पंक्ति समाधान एक होना चाहिए, तो एएनएसआई सी-उद्धृत स्ट्रिंग ( bash, kshया zsh) का उपयोग करना एक उचित समाधान है: python -c $'import sys\nfor r in range(10): print(\'rob\')'(आपको केवल एकल उद्धरण से बचने के बारे में चिंता करनी होगी (जिसे आप दोहरे उद्धरणों का उपयोग करके बच सकते हैं) और बैकस्लैश)।
19

14

बस वापसी का उपयोग करें और इसे अगली पंक्ति पर टाइप करें:

user@host:~$ python -c "import sys
> for r in range(10): print 'rob'"
rob
rob
...

6
गंभीरता से, आप कुछ करने के लिए जा रहे हैं अगर आप ऐसा करते रहें। python $(srcdir)/myscript.pyमहान न्याय के लिए।
जेसन ओरेंडोर्फ


8

समस्या importबयान के साथ नहीं है । समस्या यह है कि नियंत्रण प्रवाह विवरण एक पायथन कमांड में इनलाइन काम नहीं करते हैं। उस importकथन को किसी अन्य विवरण के साथ बदलें और आपको वही समस्या दिखाई देगी।

इसके बारे में सोचो: अजगर संभवतः सब कुछ इनलाइन नहीं कर सकता। यह समूह नियंत्रण-प्रवाह के लिए इंडेंटेशन का उपयोग करता है।


7

यदि आपका सिस्टम Posix.2 है तो उसे printfउपयोगिता की आपूर्ति करनी चाहिए :

$ printf "print 'zap'\nfor r in range(3): print 'rob'" | python
zap
rob
rob
rob

2
अच्छा समाधान, लेकिन मैं printf %b '...' | pythonजोड़ा मजबूती के लिए उपयोग करने का सुझाव देता हूं , क्योंकि यह इनपुट स्ट्रिंग में (प्रारूप विनिर्देशक) printfजैसे दृश्यों की व्याख्या करने से रोकता है %d। इसके अलावा, जब तक आप स्पष्ट रूप से अपने पाइथन कमांड स्ट्रिंग अप फ्रंट (जो भ्रमित हो सकते हैं) में शेल विस्तार लागू करना चाहते हैं ', बाहरी उद्धरण के लिए (सिंगल कोट्स) का उपयोग करना बेहतर है , दोनों विस्तार और बैकहैंड दोनों से बचने के लिए जो शेल लागू होता है डबल-उद्धृत स्ट्रिंग्स के लिए।
mklement0

5

single/double quotesऔर backslashहर जगह:

$ python -c 'exec("import sys\nfor i in range(10): print \"bob\"")'

काफी बेहतर:

$ python -c '
> import sys
> for i in range(10):
>   print "bob"
> '

इसलिए। बहुत। बेहतर।
मार्क

4

(उत्तर 23 नवंबर 10 को 19:48 बजे) मैं वास्तव में एक बड़ा अजगर नहीं हूं - लेकिन मैंने एक बार इस वाक्यविन्यास को पाया, जहां से भूल गया था, इसलिए मैंने सोचा कि मैं इसे दस्तावेज करूंगा:

यदि आप sys.stdout.writeइसके बजाय उपयोग करते हैं print( अंतर होने के नाते, sys.stdout.writeएक फ़ंक्शन के रूप में, कोष्ठक में तर्क लेता है - जबकि printनहीं ), तो एक-लाइनर के लिए, आप कमांड के आदेश forको निकालने और अर्धविराम को हटाने के साथ दूर हो सकते हैं , और वर्गाकार कोष्ठक में कमांड संलग्न करना, अर्थात:

python -c "import sys; [sys.stdout.write('rob\n') for r in range(10)]"

पता नहीं कैसे इस वाक्यविन्यास को पायथन में कहा जाएगा :)

उम्मीद है की यह मदद करेगा,

चीयर्स!


(EDIT Tue Apr 9 20:57:30 2013) ठीक है, मुझे लगता है कि मैंने आखिरकार वन-लाइनर्स में इन वर्ग कोष्ठकों के बारे में क्या पाया है; वे "सूची समझ" (जाहिरा तौर पर) हैं; पहले पायथन 2.7 में इस पर ध्यान दें:

$ STR=abc
$ echo $STR | python -c "import sys,re; a=(sys.stdout.write(line) for line in sys.stdin); print a"
<generator object <genexpr> at 0xb771461c>

तो राउंड ब्रैकेट्स / कोष्ठक में कमांड को "जनरेटर ऑब्जेक्ट" के रूप में देखा जाता है; यदि हम कॉल करके इसके माध्यम से "पुनरावृति" करते हैं next()- तो कोष्ठक के अंदर की कमांड निष्पादित की जाएगी (आउटपुट में "एबीसी" पर ध्यान दें):

$ echo $STR | python -c "import sys,re; a=(sys.stdout.write(line) for line in sys.stdin); a.next() ; print a"
abc
<generator object <genexpr> at 0xb777b734>

अगर हम अब वर्ग कोष्ठक का उपयोग करते हैं - ध्यान दें कि हमें next()कमांड निष्पादित करने के लिए कॉल करने की आवश्यकता नहीं है , यह असाइनमेंट पर तुरंत निष्पादित करता है; हालांकि, बाद में निरीक्षण से पता चलता है कि aहै None:

$ echo $STR | python -c "import sys,re; a=[sys.stdout.write(line) for line in sys.stdin]; print a"
abc
[None]

यह वर्ग ब्रैकेट मामले के लिए देखने के लिए बहुत जानकारी नहीं छोड़ता है - लेकिन मैं इस पृष्ठ पर ठोकर खाई, जो मुझे लगता है कि समझाता है:

पायथन टिप्स एंड ट्रिक्स - पहला संस्करण - पायथन ट्यूटोरियल | ड्रीम.इनकोड :

यदि आप याद करते हैं, तो एकल पंक्ति जनरेटर का मानक प्रारूप 'ब्रैकेट के अंदर लूप' के लिए एक तरह की एक लाइन है। यह एक 'वन-शॉट' iterable ऑब्जेक्ट का उत्पादन करेगा, जो एक ऐसी वस्तु है जिसे आप केवल एक दिशा में ओवररेट कर सकते हैं और जिसे आप अंत तक पहुंचने के बाद फिर से उपयोग नहीं कर सकते हैं।

एक 'लिस्ट कॉम्प्रिहेंशन' एक नियमित वन-लाइन जनरेटर के समान ही दिखता है, सिवाय इसके कि नियमित कोष्ठक - () - को वर्ग कोष्ठक द्वारा प्रतिस्थापित किया जाता है - []। एलिस्ट कॉम्प्रिहेंशन का प्रमुख एडवांटेज यह है कि 'वन-शॉट' इट्रिजेबल ऑब्जेक्ट के बजाय एक 'लिस्ट' तैयार करता है, ताकि आप इसके माध्यम से आगे-पीछे जा सकें, एलिमेंट्स, सॉर्ट आदि जोड़ सकें।

और वास्तव में यह एक सूची है - यह बस इसका पहला तत्व बन जाता है जैसे ही इसे निष्पादित किया जाता है:

$ echo $STR | python -c "import sys,re; print [sys.stdout.write(line) for line in sys.stdin].__class__"
abc
<type 'list'>
$ echo $STR | python -c "import sys,re; print [sys.stdout.write(line) for line in sys.stdin][0]"
abc
None

सूची की समझ को अन्यथा 5. दस्तावेज़ों में शामिल किया गया है : डेटा संरचनाएं: 5.1.4। सूची समझ - पायथन v2.7.4 प्रलेखन "सूची समझ सूची बनाने के लिए एक संक्षिप्त तरीका प्रदान करता है" के रूप में; संभवतः, यह वह जगह है जहाँ सूचियों की सीमित "निष्पादन" एक-लाइनरों में खेल में आती है।

खैर, आशा है कि मैं यहाँ बहुत निशान नहीं हूँ ...

EDIT2: और यहां एक नॉन-लाइनर कमांड लाइन है जिसमें दो नॉन-नेस्टेड फॉर-लूप्स हैं; दोनों "सूची बोध" वर्ग कोष्ठक के भीतर संलग्न:

$ echo $STR | python -c "import sys,re; a=[sys.stdout.write(line) for line in sys.stdin]; b=[sys.stdout.write(str(x)) for x in range(2)] ; print a ; print b"
abc
01[None]
[None, None]

ध्यान दें कि दूसरी "सूची" में bअब दो तत्व हैं, क्योंकि इसके लूप के लिए स्पष्ट रूप से दो बार भाग लिया गया है; हालाँकि, sys.stdout.write()दोनों मामलों का परिणाम (जाहिरा तौर पर) था None


4

यह वैरिएंट, बिना पाइप के विंडोज और * nix, py2 / 3 पर कमांड-लाइन पर मल्टी-लाइन स्क्रिप्ट लगाने के लिए सबसे पोर्टेबल है:

python -c "exec(\"import sys \nfor r in range(10): print('rob') \")"

(अब तक देखे गए अन्य उदाहरणों में से कोई भी ऐसा नहीं किया)

विंडोज पर नीट है:

python -c exec"""import sys \nfor r in range(10): print 'rob' """
python -c exec("""import sys \nfor r in range(10): print('rob') """)

बैश पर * / निक्स है:

python -c $'import sys \nfor r in range(10): print("rob")'

यह फ़ंक्शन किसी भी बहु-लिपि को पोर्टेबल कमांड-वन-लाइनर में बदल देता है:

def py2cmdline(script):
    exs = 'exec(%r)' % re.sub('\r\n|\r', '\n', script.rstrip())
    print('python -c "%s"' % exs.replace('"', r'\"'))

उपयोग:

>>> py2cmdline(getcliptext())
python -c "exec('print \'AA\tA\'\ntry:\n for i in 1, 2, 3:\n  print i / 0\nexcept:\n print \"\"\"longer\nmessage\"\"\"')"

इनपुट था:

print 'AA   A'
try:
 for i in 1, 2, 3:
  print i / 0
except:
 print """longer
message"""

पार मंच कोण और कनवर्टर के लिए ++। पोर्टेबिलिटी (पॉवरशेल को छोड़कर) के मामले में आपका पहला आदेश उतना ही अच्छा है, लेकिन अंततः कोई एकल, पूरी तरह से मजबूत क्रॉस-प्लेटफॉर्म सिंटैक्स नहीं है, क्योंकि दोहरे उद्धरण चिह्नों का उपयोग करने की आवश्यकता तब अनचाहे शेल विस्तार के जोखिम को सहन करती है, विंडोज को पोसिक्स जैसे गोले की तुलना में अलग-अलग पात्रों से बचने की आवश्यकता है। PowerShell v3 या उच्चतर में आप --%कमांड-स्ट्रिंग तर्क से पहले "स्टॉप-पार्सिंग" विकल्प डालकर अपनी कमांड लाइनों को काम कर सकते हैं ।
mklement0

@ mklement0 " अवांछित खोल विस्तार ": ठीक है, खोल विस्तार की तरह सम्मान में कुछ print "path is %%PATH%%"print "path is $PATH"आम तौर पर वह विकल्प होता है जो कोई स्क्रिप्ट या कमांड-लाइन में चाहता है - जब तक कि कोई प्लेटफ़ॉर्म के लिए सामान से बच न जाए। अन्य भाषाओं के साथ भी। (पायथन सिंटैक्स स्वयं नियमित रूप से% और $ का प्रतिस्पर्धात्मक तरीके से उपयोग करने का सुझाव नहीं देता है।)
kxr

यदि आप सीधे पायथन स्रोत कोड में शेल-चर संदर्भ डालते हैं, तो यह परिभाषा के अनुसार पोर्टेबल नहीं होगा। मेरे बात यह है कि भले ही आप के बजाय में प्लेटफ़ॉर्म-विशिष्ट संदर्भ का निर्माण अलग चर है कि आप पारित तर्क के रूप में एक करने के लिए एकल, "खोल से मुक्त" अजगर आदेश, कि हो सकता है हमेशा काम नहीं है, क्योंकि आप डबल-कोटेड स्ट्रिंग की रक्षा नहीं कर सकते हैं portably : उदाहरण के लिए, क्या होगा यदि आपको अपने पायथन कोड में शाब्दिक की आवश्यकता है $foo? यदि आप \$fooपोसिक्स जैसे गोले के लाभ के लिए इसे छोड़ देते हैं, तब cmd.exeभी अतिरिक्त देखेंगे \ । यह दुर्लभ हो सकता है लेकिन इसके बारे में जानने लायक है।
mklement0

Windows PowerShell में ऐसा करने की कोशिश कर रहा है, लेकिन समस्या यह है कि अजगर -c निष्पादित ("" "..." "") किसी भी आउटपुट का उत्पादन नहीं करता है, चाहे कोई भी कोड हो ... या नहीं; मैं वहां कोई भी तोड़फोड़ कर सकता हूं, और नतीजा वही होगा। मुझे लगता है कि शेल स्टडआउट और स्टेडर दोनों धाराओं को "खा रहा है" - मैं इसे कैसे थूक सकता हूं?
यूरी

2

यह स्क्रिप्ट पर्ल जैसी कमांड लाइन इंटरफ़ेस प्रदान करता है:

Pyliner - स्क्रिप्ट को कमांड लाइन (Python recipe) पर मनमाना पायथन कोड चलाने के लिए


मुझे लगता है कि वे कुछ ठीक करना चाहते थे, दूसरे उपकरण का उपयोग नहीं करना चाहते थे। वैसे भी अच्छा संकेत
enrico.bacis

मैं @ enrico.bacis से सहमत हूं, लेकिन मैं अभी भी खुश हूं कि आपने यह उत्तर जोड़ा। इस सवाल का जवाब मैं तब देता था जब मैंने इस पृष्ठ को गुगेल किया था।
tbc0

1

जब मुझे ऐसा करने की आवश्यकता होती है, तो मैं उपयोग करता हूं

python -c "$(echo -e "import sys\nsys.stdout.write('Hello World!\\\n')")"

Sys.stdout.write स्टेटमेंट में न्यूलाइन के लिए ट्रिपल बैकस्लैश नोट करें।


यह काम करता है, लेकिन जब से आप उपयोग कर रहे हैं echo -e, जो कि गैरमानक है और आपको आवश्यकता है bash, kshया zsh, आप $'...'सीधे एक तार का उपयोग कर सकते हैं, जो पलायन को भी सरल करता है:python -c $'import sys\nsys.stdout.write("Hello World!\\n")'
mklement0

यह उत्तर काम करता है, अन्य उत्तर पायथन 3 के लिए काम नहीं करते हैं

1

मैं निम्नलिखित गुणों के साथ एक समाधान चाहता था:

  1. पठनीय
  2. अन्य टूल के आउटपुट आउटपुट के लिए स्टडिन पढ़ें

दोनों आवश्यकताओं को अन्य उत्तरों में प्रदान नहीं किया गया था, इसलिए यहां बताया गया है कि कमांड लाइन पर सब कुछ करते हुए स्टड कैसे पढ़ें:

grep special_string -r | sort | python3 <(cat <<EOF
import sys
for line in sys.stdin:
    tokens = line.split()
    if len(tokens) == 4:
        print("%-45s %7.3f    %s    %s" % (tokens[0], float(tokens[1]), tokens[2], tokens[3]))
EOF
)

0

एक और विकल्प है, sys.stdout.write कोई नहीं, जो सूची को खाली रखता है

cat somefile.log | python -c "import sys; [sys.stdin में लाइन के लिए लाइन यदि sys.stdout.write (लाइन * 2)]"


0

यदि आप स्टडिन को स्पर्श नहीं करना चाहते हैं और मान लें कि आपने "python cmdfile.py" पास कर लिया है, तो आप निम्नलिखित को bash शेल से कर सकते हैं:

$ python  <(printf "word=raw_input('Enter word: ')\nimport sys\nfor i in range(5):\n    print(word)")

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


++ स्क्रिप्ट के साथ "ऊपर" का उपयोग नहीं करने के लिए (हालांकि -c "$(...)"ऐसा ही है, और POSIX- आज्ञाकारी है); <(...)निर्माण को एक नाम देने के लिए : प्रक्रिया प्रतिस्थापन ; यह भी में काम करता है kshऔर zsh
19-28 में mklement0
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.