242
votes
Closed. This question isopinion-based. It is not currently accepting answers.
Closed7 years ago.
Locked. This question and its answers arelocked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.

I currently do my textfile manipulation through a bunch of badly remembered AWK, sed, Bash and a tiny bit of Perl.

I've seen mentioned a few places that python is good for this kind of thing. How can I use Python to replace shell scripting, AWK, sed and friends?

askedOct 16, 2008 at 17:11
Chris Jefferson's user avatar
4
  • 3
    pythonpy is a good competitor for awk and sed using python syntax:github.com/Russell91/pythonpyCommentedSep 13, 2014 at 5:57
  • 4
    you can use shellpy that was designed with an idea in mind to replace bash/sh with pythongithub.com/lamerman/shellpyCommentedFeb 14, 2016 at 15:29
  • This is my question, I don't understand why it is opinion based. The top answer lists each of the main things a shell does, and tells you how to do them in python. That in my opinion answers the question in a non-opinion way.CommentedApr 9, 2018 at 10:03
  • This question, and it's closure, are being discussed on metahereCommentedApr 18, 2018 at 10:40
Comments disabled on deleted / locked posts / reviews | 

17 Answers17

144
votes

Any shell has several sets of features.

  • The Essential Linux/Unix commands. All of these are available through thesubprocess library. This isn't always the best first choice for doingall external commands. Look also atshutil for some commands that are separate Linux commands, but you could probably implement directly in your Python scripts. Another huge batch of Linux commands are in theos library; you can do these more simply in Python.

    And -- bonus! -- more quickly. Each separate Linux command in the shell (with a few exceptions) forks a subprocess. By using Pythonshutil andos modules, you don't fork a subprocess.

  • The shell environment features. This includes stuff that sets a command's environment (current directory and environment variables and what-not). You can easily manage this from Python directly.

  • The shell programming features. This is all the process status code checking, the various logic commands (if, while, for, etc.) the test command and all of it's relatives. The function definition stuff. This is all much, much easier in Python. This is one of the huge victories in getting rid of bash and doing it in Python.

  • Interaction features. This includes command history and what-not. You don't need this for writing shell scripts. This is only for human interaction, and not for script-writing.

  • The shell file management features. This includes redirection and pipelines. This is trickier. Much of this can be done with subprocess. But some things that are easy in the shell are unpleasant in Python. Specifically stuff like(a | b; c ) | something >result. This runs two processes in parallel (with output ofa as input tob), followed by a third process. The output from that sequence is run in parallel withsomething and the output is collected into a file namedresult. That's just complex to express in any other language.

Specific programs (awk, sed, grep, etc.) can often be rewritten as Python modules. Don't go overboard. Replace what you need and evolve your "grep" module. Don't start out writing a Python module that replaces "grep".

The best thing is that you can do this in steps.

  1. Replace AWK and PERL with Python. Leave everything else alone.
  2. Look at replacing GREP with Python. This can be a bit more complex, but your version of GREP can be tailored to your processing needs.
  3. Look at replacing FIND with Python loops that useos.walk. This is a big win because you don't spawn as many processes.
  4. Look at replacing common shell logic (loops, decisions, etc.) with Python scripts.
answeredOct 16, 2008 at 17:41
S.Lott's user avatar
Sign up to request clarification or add additional context in comments.

8 Comments

wrote: "Interaction features. This includes command history and what-not. You don't need this." I'm afraid no one could tell what a person really needs or not. Perhaps he does. Besides, these facilities make a lot of sense in an interactive shell, taking as an example the difference between Idle and IPython.
I sincerely wish people would ditch shell scripting altogether. I understand that hacking is practically a religion in the *nix world but I get really tired of trying to interpret all the hackish workarounds implanted in the OS. The novelty of microtools (awk, sed, top, base, etc) wore off the day everybody decided to roll their own version. I cringe when I imagine the amount of man-hours wasted on crappy little tools that could easy be replaced by a couple well designed Python modules. ::sigh::
I disagree @EvanPlaice because the python version of severalfind scripts I have is ugly and long and unmaintainable in comparison. Many thingsshould be shell scripts, many othersshould not. Not everything needs to be only one of Python or BASH (or anything else).
@mikebabcock Ideally there would be a complete library that implements all of the micro-tools that are made available by the basic *nix stack. Functions like find() and last() would be included and instead of pipes, a combination of currying and lazy-loading would handle gluing it all together. Wouldn't it be nice to have a POSIX scripting environment that works in a standard way across all distros? Nothing like that exists, yet...
The point about shell pipelines (such as(a | b; c ) | something >result) is somewhat mitigated by it being trivially easy to pass shell pipelines tosubprocess methods usingshell=True
|
103
votes

Yes, of course :)

Take a look at these libraries which help youNever write shell scripts again (Plumbum's motto).

Also, if you want to replace awk, sed and grep with something Python based then I recommendpyp -

"The Pyed Piper", or pyp, is a linux command line text manipulation tool similar to awk or sed, but which uses standard python string and list methods as well as custom functions evolved to generate fast results in an intense production environment.

answeredOct 16, 2012 at 13:37
Piotr Dobrogost's user avatar

1 Comment

Also have a look at Envoy, which is an alternative to shgithub.com/kennethreitz/envoy
57
votes

I just discovered how to combine the best parts of bash and ipython. Up to now this seems more comfortable to me than using subprocess and so on. You can easily copy big parts of existing bash scripts and e.g. add error handling in the python way :)And here is my result:

#!/usr/bin/env ipython3# *** How to have the most comfort scripting experience of your life ***# ######################################################################## … by using ipython for scripting combined with subcommands from bash!## 1. echo "#!/usr/bin/env ipython3" > scriptname.ipy    # creates new ipy-file## 2. chmod +x scriptname.ipy                            # make in executable## 3. starting with line 2, write normal python or do some of#    the ! magic of ipython, so that you can use unix commands#    within python and even assign their output to a variable via#    var = !cmd1 | cmd2 | cmd3                          # enjoy ;)## 4. run via ./scriptname.ipy - if it fails with recognizing % and !#    but parses raw python fine, please check again for the .ipy suffix# ugly example, please go and find more in the wildfiles = !ls *.* | grep "y"for file in files:  !echo $file | grep "p"# sorry for this nonsense example ;)

See IPython docs onsystem shell commands and using itas a system shell.

anatoly techtonik's user avatar
anatoly techtonik
20.7k14 gold badges133 silver badges146 bronze badges
answeredMar 29, 2013 at 22:49
TheK's user avatar

3 Comments

Upvoted because for some bizarre reason, no-one else has mentioned !-commands in IPython, which are absolutely key; especially since you can also assign their output to a variable (list of lines) as infilelines = ! cat myfile
And you can use python variables as$var in a shell command? Wow. This should be the accepted answer.
And you can also use it from within the jupyter notebooks
44
votes

As of 2015 and Python 3.4's release, there's now a reasonably complete user-interactive shell available at:http://xon.sh/ orhttps://github.com/scopatz/xonsh

Thedemonstration video does not show pipes being used, but they ARE supported when in the default shell mode.

Xonsh ('conch') tries very hard to emulate bash, so things you've already gained muscle memory for, like

env | uniq | sort -r | grep PATH

or

my-web-server 2>&1 | my-log-sorter

will still work fine.

The tutorial is quite lengthy and seems to cover a significant amount of the functionality someone would generally expect at a ash or bash prompt:

  • Compiles, Evaluates, & Executes!
  • Command History and Tab Completion
  • Help & Superhelp with? &??
  • Aliases & Customized Prompts
  • Executes Commands and/or*.xsh Scripts which can also be imported
  • Environment Variables including Lookup with${}
  • Input/Output Redirection and Combining
  • Background Jobs & Job Control
  • Nesting Subprocesses, Pipes, and Coprocesses
  • Subprocess-mode when a command exists, Python-mode otherwise
  • Captured Subprocess with$(), Uncaptured Subprocess with$[], Python Evaluation with@()
  • Filename Globbing with* or Regular Expression Filename Globbing with Backticks
Michael come lately's user avatar
Michael come lately
9,6418 gold badges70 silver badges97 bronze badges
answeredJun 3, 2015 at 10:08
Kamilion's user avatar

2 Comments

But why does it seem like all of these answers are just reinventing the wheelfor people who don't know bash? I've gotten moderately comfortable with bash and every one of these answers looks like it will end up being more work for little benefit. These answers are all aimed at python people who are afraid of (or don't want to spend time learning) bash, am I right?
Seems it has some disadvantages like requirement to use.xsh extension for files with the xonsh code:github.com/xonsh/xonsh/issues/2478. Otherwise you have to useevalx to call it directly from the.py files.
31
votes
  • If you want to use Python as a shell, why not have a look atIPython ? It is also good to learn interactively the language.
  • If you do a lot of text manipulation, and if you use Vim as a text editor, you can also directly write plugins for Vim in python. just type ":help python" in Vim and follow the instructions or have a look at thispresentation. It is so easy and powerfull to write functions that you will use directly in your editor!
Catskul's user avatar
Catskul
19.8k16 gold badges90 silver badges122 bronze badges
answeredOct 16, 2008 at 18:16
Mapad's user avatar

3 Comments

there's an ipython profile called 'sh' that makes the interpretervery much like a shell.
The ipython 'sh' profile has been removed for some time now.
>>>result = !dmesg | grep -i 'usb' #the ! operator does it all
16
votes

In the beginning there was sh, sed, and awk (and find, and grep, and...). It was good. But awk can be an odd little beast and hard to remember if you don't use it often. Then the great camel created Perl. Perl was a system administrator's dream. It was like shell scripting on steroids. Text processing, including regular expressions were just part of the language. Then it got ugly... People tried to make big applications with Perl. Now, don't get me wrong, Perl can be an application, but it can (can!) look like a mess if you're not really careful. Then there is all this flat data business. It's enough to drive a programmer nuts.

Enter Python, Ruby, et al. These are really very good general purpose languages. They support text processing, and do it well (though perhaps not as tightly entwined in the basic core of the language). But they also scale up very well, and still have nice looking code at the end of the day. They also have developed pretty hefty communities with plenty of libraries for most anything.

Now, much of the negativeness towards Perl is a matter of opinion, and certainly some people can write very clean Perl, but with this many people complaining about it being too easy to create obfuscated code, you know some grain of truth is there. The question really becomes then, are you ever going to use this language for more than simple bash script replacements. If not, learn some more Perl.. it is absolutely fantastic for that. If, on the other hand, you want a language that will grow with you as you want to do more, may I suggest Python or Ruby.

Either way, good luck!

answeredOct 16, 2008 at 20:58
MattG's user avatar

Comments

9
votes

I suggest the awesome online bookDive Into Python. It's how I learned the language originally.

Beyond teaching you the basic structure of the language, and a whole lot of useful data structures, it has a good chapter onfile handling and subsequent chapters onregular expressions and more.

answeredOct 16, 2008 at 17:40
Dan Lenski's user avatar

1 Comment

... main issue of link-only answers.
7
votes

Adding to previous answers: check thepexpect module for dealing with interactive commands (adduser, passwd etc.)

answeredOct 16, 2008 at 22:05
Federico A. Ramponi's user avatar

Comments

7
votes

One reason I love Python is that it is much better standardized than the POSIX tools. I have to double and triple check that each bit is compatible with other operating systems. A program written on a Linux system might not work the same on a BSD system of OSX. With Python, I just have to check that the target system has a sufficiently modern version of Python.

Even better, a program written in standard Python will even run on Windows!

answeredMay 24, 2013 at 1:23
Hal Canary's user avatar

1 Comment

"a program written in standard Python will even run on Windows": no kidding?
6
votes

I will give here my opinion based on experience:

For shell:

  • shell can very easily spawn read-only code. Write it and when you come back to it, you will never figure out what you did again. It's very easy to accomplish this.
  • shell can do A LOT of text processing, splitting, etc in one line with pipes.
  • it is the best glue language when it comes to integrate the call of programs in different programming languages.

For python:

  • if you want portability to windows included, use python.
  • python can be better when you must manipulate just more than text, such as collections of numbers. For this, I recommend python.

I usually choose bash for most of the things, but when I have something that must cross windows boundaries, I just use python.

answeredDec 1, 2013 at 14:40
Germán Diago's user avatar

Comments

4
votes

pythonpy is a tool that provides easy access to many of the features from awk and sed, but using python syntax:

$ echo me2 | py -x 're.sub("me", "you", x)'you2
answeredSep 13, 2014 at 5:55
RussellStewart's user avatar

Comments

3
votes

I have built semi-long shell scripts (300-500 lines) and Python code which does similar functionality. When many external commands are being executed, I find the shell is easier to use. Perl is also a good option when there is lots of text manipulation.

answeredOct 16, 2008 at 21:49
Mike Davis's user avatar

Comments

3
votes

While researching this topic, I foundthis proof-of-concept code (via a comment athttp://jlebar.com/2010/2/1/Replacing_Bash.html) that lets you "write shell-like pipelines in Python using a terse syntax, and leveraging existing system tools where they make sense":

for line in sh("cat /tmp/junk2") | cut(d=',',f=1) | 'sort' | uniq:    sys.stdout.write(line)
answeredOct 3, 2010 at 20:21
Nickolay's user avatar

Comments

2
votes

Your best bet is a tool that is specifically geared towards your problem. If it's processing text files, then Sed, Awk and Perl are the top contenders. Python is a general-purposedynamic language. As with any general purpose language, there's support for file-manipulation, but that isn't what it's core purpose is. I would consider Python or Ruby if I had a requirement for a dynamic language in particular.

In short, learn Sed and Awk really well, plus all the other goodies that come with your flavour of *nix (All the Bash built-ins, grep, tr and so forth). If it's text file processing you're interested in, you're already using the right stuff.

answeredOct 16, 2008 at 18:14
Eric Smith's user avatar

Comments

2
votes

You can use python instead of bash with theShellPy library.

Here is an example that downloads avatar of Python user from Github:

import jsonimport osimport tempfile# get the api answer with curlanswer = `curl https://api.github.com/users/python# syntactic sugar for checking returncode of executed process for zeroif answer:    answer_json = json.loads(answer.stdout)    avatar_url = answer_json['avatar_url']    destination = os.path.join(tempfile.gettempdir(), 'python.png')    # execute curl once again, this time to get the image    result = `curl {avatar_url} > {destination}    if result:        # if there were no problems show the file        p`ls -l {destination}    else:        print('Failed to download avatar')    print('Avatar downloaded')else:    print('Failed to access github api')

As you can see, all expressions inside of grave accent ( ` ) symbol are executed in shell. And in Python code, you can capture results of this execution and perform actions on it. For example:

log = `git log --pretty=oneline --grep='Create'

This line will first executegit log --pretty=oneline --grep='Create' in shell and then assign the result to the log variable. The result has the following properties:

stdout the whole text from stdout of the executed process

stderr the whole text from stderr of the executed process

returncode returncode of the execution

This is general overview of the library, more detailed description with examples can be foundhere.

Jason's user avatar
Jason
2,3042 gold badges19 silver badges25 bronze badges
answeredFeb 16, 2016 at 21:23
Alexander Ponomarev's user avatar

Comments

1
vote

If your textfile manipulation usually is one-time, possibly done on the shell-prompt, you will not get anything better from python.

On the other hand, if you usually have to do the same (or similar) task over and over, and you have to write your scripts for doing that, then python is great - and you can easily create your own libraries (you can do that with shell scripts too, but it's more cumbersome).

A very simple example to get a feeling.

import popen2stdout_text, stdin_text=popen2.popen2("your-shell-command-here")for line in stdout_text:  if line.startswith("#"):    pass  else    jobID=int(line.split(",")[0].split()[1].lstrip("<").rstrip(">"))    # do something with jobID

Check also sys and getopt module, they are the first you will need.

answeredOct 16, 2008 at 17:42
Davide's user avatar

Comments

1
vote

I have published a package on PyPI:ez.
Usepip install ez to install it.

It has packed common commands in shell and nicely my lib uses basically the same syntax as shell. e.g., cp(source, destination) can handle both file and folder! (wrapper of shutil.copy shutil.copytree and it decides when to use which one). Even more nicely, it can support vectorization like R!

Another example: no os.walk, use fls(path, regex) to recursively find files and filter with regular expression and it returns a list of files with or without fullpath

Final example: you can combine them to write very simply scripts:
files = fls('.','py$'); cp(files, myDir)

Definitely check it out! It has cost me hundreds of hours to write/improve it!

Jason's user avatar
Jason
2,3042 gold badges19 silver badges25 bronze badges
answeredJan 10, 2015 at 21:14
Jerry T's user avatar

1 Comment

Looks interesting, but I can't break through the unformatted docs atpypi.python.org/pypi/ez , sorry...

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.