Re: Multi-line commands with 'python -c'
Peter Otten __pete...@web.de wrote: Duncan Booth wrote: Chris Angelico ros...@gmail.com wrote: On Sat, May 31, 2014 at 7:42 AM, Devin Jeanpierre jeanpierr...@gmail.com wrote: In unix shells you can literally use a new line. Or is that only bash? You can in bash, I know, but it's fiddly to type it; and more importantly, it's not a good point in the this is cleaner than a series of pipes argument. My primary recommendation, of course, was a three-line script saved as an actual file, but for a more direct parallel to the pipe-it-three-ways model, I wanted to use -c. and you also wrote originally that it's fiddly to edit. I think that Windows Powershell has (at least in the current ISE command line) got the editing a bit better. It's a minor difference though and it has taken Microsoft about 30 years to get to that point. What may be a larger difference, or may just be my lack of Linux-foo, is this: PS C:\python33 $script = @ import os for root, dirs, files in os.walk(.): if len(dirs + files) == 1: print(root) @ PS C:\python33 python -c $script .\Doc .\Lib\concurrent\__pycache__ .\Lib\curses\__pycache__ ... which is a style I've found useful for example when running a group of related timeit.py commands as I can put things like multi-line setup statements in a variable and then have a simpler command to repeat. But bash as far as I can won't let me do that: $ script='import os for root, dirs, files in os.walk(.): if len(dirs + files) == 1: print(root) ' $ python -c $script File string, line 1 import ^ SyntaxError: invalid syntax $ script='import os for root, dirs, files in os.walk(.): if len(dirs + files) == 1: print(root) ' $ python3 -c $script . ./heureka $ python3 -c 'import sys; print(sys.argv)' $script ['-c', 'import', 'os', 'for', 'root,', 'dirs,', 'files', 'in', 'os.walk(.):', 'if', 'len(dirs', '+', 'files)', '==', '1:', 'print(root)'] $ python3 -c 'import sys; print(sys.argv)' $script ['-c', 'import os\nfor root, dirs, files in os.walk(.):\nif len(dirs + files) == 1:\nprint(root)\n'] Thanks, I thought there must be a way to do that (and I should have remembered it). It nicely shows up the difference between the *nix shells that are all about processing the command line as a string and the Powershell way where it is all about objects (so a single value stays as a single argument). -- Duncan Booth -- https://mail.python.org/mailman/listinfo/python-list
Re: Multi-line commands with 'python -c'
Chris Angelico ros...@gmail.com wrote: On Sat, May 31, 2014 at 7:42 AM, Devin Jeanpierre jeanpierr...@gmail.com wrote: In unix shells you can literally use a new line. Or is that only bash? You can in bash, I know, but it's fiddly to type it; and more importantly, it's not a good point in the this is cleaner than a series of pipes argument. My primary recommendation, of course, was a three-line script saved as an actual file, but for a more direct parallel to the pipe-it-three-ways model, I wanted to use -c. and you also wrote originally that it's fiddly to edit. I think that Windows Powershell has (at least in the current ISE command line) got the editing a bit better. It's a minor difference though and it has taken Microsoft about 30 years to get to that point. What may be a larger difference, or may just be my lack of Linux-foo, is this: PS C:\python33 $script = @ import os for root, dirs, files in os.walk(.): if len(dirs + files) == 1: print(root) @ PS C:\python33 python -c $script .\Doc .\Lib\concurrent\__pycache__ .\Lib\curses\__pycache__ ... which is a style I've found useful for example when running a group of related timeit.py commands as I can put things like multi-line setup statements in a variable and then have a simpler command to repeat. But bash as far as I can won't let me do that: $ script='import os for root, dirs, files in os.walk(.): if len(dirs + files) == 1: print(root) ' $ python -c $script File string, line 1 import ^ SyntaxError: invalid syntax -- Duncan Booth -- https://mail.python.org/mailman/listinfo/python-list
Re: Multi-line commands with 'python -c'
Duncan Booth wrote: Chris Angelico ros...@gmail.com wrote: On Sat, May 31, 2014 at 7:42 AM, Devin Jeanpierre jeanpierr...@gmail.com wrote: In unix shells you can literally use a new line. Or is that only bash? You can in bash, I know, but it's fiddly to type it; and more importantly, it's not a good point in the this is cleaner than a series of pipes argument. My primary recommendation, of course, was a three-line script saved as an actual file, but for a more direct parallel to the pipe-it-three-ways model, I wanted to use -c. and you also wrote originally that it's fiddly to edit. I think that Windows Powershell has (at least in the current ISE command line) got the editing a bit better. It's a minor difference though and it has taken Microsoft about 30 years to get to that point. What may be a larger difference, or may just be my lack of Linux-foo, is this: PS C:\python33 $script = @ import os for root, dirs, files in os.walk(.): if len(dirs + files) == 1: print(root) @ PS C:\python33 python -c $script .\Doc .\Lib\concurrent\__pycache__ .\Lib\curses\__pycache__ ... which is a style I've found useful for example when running a group of related timeit.py commands as I can put things like multi-line setup statements in a variable and then have a simpler command to repeat. But bash as far as I can won't let me do that: $ script='import os for root, dirs, files in os.walk(.): if len(dirs + files) == 1: print(root) ' $ python -c $script File string, line 1 import ^ SyntaxError: invalid syntax $ script='import os for root, dirs, files in os.walk(.): if len(dirs + files) == 1: print(root) ' $ python3 -c $script . ./heureka $ python3 -c 'import sys; print(sys.argv)' $script ['-c', 'import', 'os', 'for', 'root,', 'dirs,', 'files', 'in', 'os.walk(.):', 'if', 'len(dirs', '+', 'files)', '==', '1:', 'print(root)'] $ python3 -c 'import sys; print(sys.argv)' $script ['-c', 'import os\nfor root, dirs, files in os.walk(.):\nif len(dirs + files) == 1:\nprint(root)\n'] -- https://mail.python.org/mailman/listinfo/python-list
Re: Multi-line commands with 'python -c'
On Friday, May 30, 2014 6:22:24 AM UTC+5:30, Chris Angelico wrote: Since lines are so critical to Python syntax, I'm a little surprised there's no majorly obvious solution to this... or maybe I'm just blind. Problem: Translate this into a shell one-liner: import os for root, dirs, files in os.walk(.): if len(dirs + files) == 1: print(root) I would have thought this would work: python -m os -c 'for root, dirs, files in os.walk(.): if len(dirs + files) == 1: print(root)' Unfortunately doesn't But did show up a small doc-bug: This fact is not documented in $ man python but is documented in $ python -h Anyways... I thought when one signs up for python one has to sign an affidavit saying: I shall not write one-liners\n * 100 -- https://mail.python.org/mailman/listinfo/python-list
Re: Multi-line commands with 'python -c'
On Friday, May 30, 2014 11:34:36 AM UTC+5:30, Rustom Mody wrote: On Friday, May 30, 2014 6:22:24 AM UTC+5:30, Chris Angelico wrote: Since lines are so critical to Python syntax, I'm a little surprised there's no majorly obvious solution to this... or maybe I'm just blind. Problem: Translate this into a shell one-liner: import os for root, dirs, files in os.walk(.): if len(dirs + files) == 1: print(root) Heres a (pr) approx $ python -c 'import os, pprint; pprint.pprint ([ r for r, d, f in os.walk(.) if len(d+f) != 1])' Mysterious that print after a ; is fine whereas for is not Anyways... I thought when one signs up for python one has to sign an affidavit saying: I shall not write one-liners\n * 100 I hope youve signed it by now wink -- https://mail.python.org/mailman/listinfo/python-list
Re: Multi-line commands with 'python -c'
On Friday, May 30, 2014 12:15:46 PM UTC+5:30, Rustom Mody wrote: Heres a (pr) approx $ python -c 'import os, pprint; pprint.pprint ([ r for r, d, f in os.walk(.) if len(d+f) != 1])' Without pprint: (pooor) python -c 'import os; print \n.join([ r for r, d, f in os.walk(.) if len(d+f) != 1])' Or (poor) python -c 'from os import walk; print \n.join([ r for r, d, f in walk(.) if len(d+f) != 1])' -- https://mail.python.org/mailman/listinfo/python-list
Re: Multi-line commands with 'python -c'
On Fri, May 30, 2014 at 4:04 PM, Rustom Mody rustompm...@gmail.com wrote: I thought when one signs up for python one has to sign an affidavit saying: I shall not write one-liners\n * 100 Certainly not. I write all my list comps on one line! *ducking for cover* ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Multi-line commands with 'python -c'
Rustom Mody wrote: On Friday, May 30, 2014 12:15:46 PM UTC+5:30, Rustom Mody wrote: Heres a (pr) approx $ python -c 'import os, pprint; pprint.pprint ([ r for r, d, f in os.walk(.) if len(d+f) != 1])' Without pprint: (pooor) python -c 'import os; print \n.join([ r for r, d, f in os.walk(.) if len(d+f) != 1])' Or (poor) python -c 'from os import walk; print \n.join([ r for r, d, f in walk(.) if len(d+f) != 1])' If there are a lot of matching folders: $ python -c 'import os, sys; sys.stdout.writelines(p + \n for p, f, n in os.walk(.) if len(n+f) == 1)' With a little help from the shell: $ echo -e import os\nfor p, f, n in os.walk('.'):\n if len(f+n) == 1: print(p) | python -- https://mail.python.org/mailman/listinfo/python-list
Re: Multi-line commands with 'python -c'
On Friday, May 30, 2014 12:50:31 PM UTC+5:30, Chris Angelico wrote: On Fri, May 30, 2014 at 4:04 PM, Rustom Mody wrote: I thought when one signs up for python one has to sign an affidavit saying: I shall not write one-liners\n * 100 Certainly not. I write all my list comps on one line! *ducking for cover* Heres a more vile misuse of python3's print-as-function + list-comp-as-for: python3 -c 'from os import walk; [print(r) for r, d, f in walk(.) if len(d+f) == 1]' Well if C programmers can use ',' as one-line ';' and '?:' as one-line if why not python also? [To noobs who are reading: Dont do this!] -- https://mail.python.org/mailman/listinfo/python-list
Re: Multi-line commands with 'python -c'
On Fri, May 30, 2014 at 10:47 PM, Rustom Mody rustompm...@gmail.com wrote: On Friday, May 30, 2014 12:50:31 PM UTC+5:30, Chris Angelico wrote: On Fri, May 30, 2014 at 4:04 PM, Rustom Mody wrote: I thought when one signs up for python one has to sign an affidavit saying: I shall not write one-liners\n * 100 Certainly not. I write all my list comps on one line! *ducking for cover* Heres a more vile misuse of python3's print-as-function + list-comp-as-for: python3 -c 'from os import walk; [print(r) for r, d, f in walk(.) if len(d+f) == 1]' Well if C programmers can use ',' as one-line ';' and '?:' as one-line if why not python also? [To noobs who are reading: Dont do this!] I actually crafted the exact same vile misuse, prior to asking the question. https://lists.debian.org/debian-user/2014/05/msg02019.html Modulo trivialities like whitespace and the from-import, it's exactly the same as your version. Incidentally, C's ?: operator maps to Python's ternary if/else operator, which most definitely is valid in a one-liner. So it's just the semicolon that you're looking at. In C, you can combine any two statements onto one line; in Python, certain statements may not follow a semicolon. So it's not really ; and ?: that are the point here, but that Python, with its stricter rules about newlines (as opposed to any whitespace), doesn't seem to have a convenient notation for putting multiple lines into a -c command. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Multi-line commands with 'python -c'
On 5/30/2014 2:45 AM, Rustom Mody wrote: $ python -c 'import os, pprint; pprint.pprint ([ r for r, d, f in os.walk(.) if len(d+f) != 1])' Mysterious that print after a ; is fine whereas for is not Not at all. Simple statememts can follow ; or :, compound statements cannot. -- Terry Jan Reedy -- https://mail.python.org/mailman/listinfo/python-list
Re: Multi-line commands with 'python -c'
Chris Angelico ros...@gmail.com wrote: Problem: Translate this into a shell one-liner: import os for root, dirs, files in os.walk(.): if len(dirs + files) == 1: print(root) This is one area where Windows seems to do better than Linux shells: PS C:\python33 python -c import os`nfor root, dirs, files in os.walk('.'):`n if len(dirs + files) == 1: print(root)`n .\Doc .\Lib\concurrent\__pycache__ .\Lib\curses\__pycache__ ... The `n shell escaped newline is interpreted well before Python runs. Also the multiline version works and in Powershell ISE up-arrow pulls it back as a single unit for easy editing: PS C:\python33 python -c @ import os for root, dirs, files in os.walk('.'): if len(dirs + files) == 1: print(root) @ .\Doc .\Lib\concurrent\__pycache__ .\Lib\curses\__pycache__ ... and so on ... -- Duncan Booth -- https://mail.python.org/mailman/listinfo/python-list
Re: Multi-line commands with 'python -c'
In unix shells you can literally use a new line. Or is that only bash? -- Devin On Fri, May 30, 2014 at 2:11 PM, Duncan Booth duncan.booth@invalid.invalid wrote: Chris Angelico ros...@gmail.com wrote: Problem: Translate this into a shell one-liner: import os for root, dirs, files in os.walk(.): if len(dirs + files) == 1: print(root) This is one area where Windows seems to do better than Linux shells: PS C:\python33 python -c import os`nfor root, dirs, files in os.walk('.'):`nif len(dirs + files) == 1: print(root)`n .\Doc .\Lib\concurrent\__pycache__ .\Lib\curses\__pycache__ ... The `n shell escaped newline is interpreted well before Python runs. Also the multiline version works and in Powershell ISE up-arrow pulls it back as a single unit for easy editing: PS C:\python33 python -c @ import os for root, dirs, files in os.walk('.'): if len(dirs + files) == 1: print(root) @ .\Doc .\Lib\concurrent\__pycache__ .\Lib\curses\__pycache__ ... and so on ... -- Duncan Booth -- https://mail.python.org/mailman/listinfo/python-list -- https://mail.python.org/mailman/listinfo/python-list
Re: Multi-line commands with 'python -c'
On Sat, May 31, 2014 at 7:42 AM, Devin Jeanpierre jeanpierr...@gmail.com wrote: In unix shells you can literally use a new line. Or is that only bash? You can in bash, I know, but it's fiddly to type it; and more importantly, it's not a good point in the this is cleaner than a series of pipes argument. My primary recommendation, of course, was a three-line script saved as an actual file, but for a more direct parallel to the pipe-it-three-ways model, I wanted to use -c. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Multi-line commands with 'python -c'
Since lines are so critical to Python syntax, I'm a little surprised there's no majorly obvious solution to this... or maybe I'm just blind. Problem: Translate this into a shell one-liner: import os for root, dirs, files in os.walk(.): if len(dirs + files) == 1: print(root) Solution 1: SyntaxError python -c 'import os; for root, dirs, files in os.walk(.): if len(dirs + files) == 1: print(root)' You can't put a 'for' statement after an 'import' with just a semicolon. Solution 2: SyntaxError python -c 'import os\nfor root, dirs, files in os.walk(.): if len(dirs + files) == 1: print(root)' You can't put a backslash escape into your code like that! Makes no sense. Solution 3: Silence python -c 'import os' -c 'for root, dirs, files in os.walk(.): if len(dirs + files) == 1: print(root)' Haven't dug into exactly what this does, but the docs say that -c terminates the option list, so I would guess that the second -c and its arg get passed to the script. Solution 4: Rely on the shell's ability to pass newlines inside arguments $ python -c 'import os for root, dirs, files in os.walk(.): if len(dirs + files) == 1: print(root) ' That works, but at that point, you aren't writing a one-liner any more. It's also fiddly to edit. Is there a better way to put multiple virtual lines into a 'python -c' command? ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Multi-line commands with 'python -c'
On Thursday, May 29, 2014, Chris Angelico ros...@gmail.com javascript:_e(%7B%7D,'cvml','ros...@gmail.com'); wrote: Since lines are so critical to Python syntax, I'm a little surprised there's no majorly obvious solution to this... or maybe I'm just blind. Problem: Translate this into a shell one-liner: import os for root, dirs, files in os.walk(.): if len(dirs + files) == 1: print(root) snip Is there a better way to put multiple virtual lines into a 'python -c' command? You can always cheat: $ python -c 'exec(import os\nfor root, dirs, files in os.walk(\.\):\n if len(dirs + files) == 1: print(root))' Doesn't do much for being long and fiddly, though. -- Zach Sent from an iPad, please bear with any brevity, uncaught auto-uncorrections, HTML, or other annoyances. Suggestions for a great (not just 'good') email app are welcome. -- Sent from Gmail Mobile -- https://mail.python.org/mailman/listinfo/python-list
Re: Multi-line commands with 'python -c'
On Fri, May 30, 2014 at 12:34 PM, Zachary Ware zachary.ware+pyl...@gmail.com wrote: You can always cheat: $ python -c 'exec(import os\nfor root, dirs, files in os.walk(\.\):\n if len(dirs + files) == 1: print(root))' Doesn't do much for being long and fiddly, though. Not really, no! Heh. I wrote that in competition against a theoretical solution involving shell commands and pipes and so on, with the intention being that the Python version could be a simple shell one-liner, just as the pipe version could. (The task: Find all directories with exactly one subdirectory or file in them, not counting dot and dot-dot. Python's os.walk() is pretty much perfect for that.) I tried fiddling with __import__() rather than the import statement, but it didn't really aid clarity much. ChrisA -- https://mail.python.org/mailman/listinfo/python-list