That's What She Sed
sed is a stream editor. You can use is for stud-level find and replace.
echo "The quick brown fox jumps over the lazy dog." | sed "s/[aeiou]/*/g"
Th* q**ck br*wn f*x j*mps *v*r th* l*zy d*g.
This demonstrates passing a string from echo piped to sed, which runs a substitution function on the values, the passes the result to stdout.
Input
sed can read from stdin or from a list of files. The latter is nicely paired with other commands like ag or find.
# find some files
jg@jg ~/c/p/r/junk> find . -type file -name "*.txt"
./b.txt
./a.txt
./foo/c.txt
# join the names and pass to the next command
jg@jg ~/c/p/r/junk> find . -type file -name "*.txt" | xargs
./b.txt ./a.txt ./foo/c.txt
# throw that list of file names onto the end of sed
jg@jg ~/c/p/r/junk> find . -type file -name "*.txt" | xargs sed ""
beer
blueberry
apple
avocado
coffee
cherry
This just reads the files and does “” to them. Not very exciting. Let’s do the same substitution function we did before.
jg@jg ~/c/p/r/junk> find . -type file -name "*.txt" | xargs sed "s/[aeiou]/*/g"
b**r
bl**b*rry
*ppl*
*v*c*d*
c*ff**
ch*rry
Cool, right? It’s not really useful yet, though, since the result is just going to stdout.
Inplace Replacements
When you’re content from files, you can make replacements in the file and automatically make a backup.
jg@jg ~/c/p/r/junk> find . -type file -name "*.txt" | xargs sed -i ".backup" "s/[aeiou]/*/g"
This does the same substitution as before, but saves the new file and a .backup
version.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: a.txt
new file: a.txt.backup
modified: b.txt
new file: b.txt.backup
modified: foo/c.txt
new file: foo/c.txt.backup
If you like to live on the edge (or are comfortably under version control), you
can skip the backup file by specifying -i ""
.
Multiple Commands
Another super cool option is to tell sed to use a list of commands in a file, allowing you to perform a bunch of operations on the stream.
Assume you have a file sed.functions
containing
s/[aeiou]/*/g
s/[abc]/|/g
you could do
jg@jg ~/c/p/r/junk> find . -type file -name "*.txt" | xargs sed -f sed.functions
|**r
|l**|*rry
*ppl*
*v*|*d*
|*ff**
|h*rry
Summary
That’s just an intro. There’s a lot more you can do, but this should help you get started.