- 1974
- Lee E. McMahon
- "Stream EDitor"
- line-oriented text processing utility
cli
sed [OPTION] [SCRIPT] [INPUTFILE]
-e | expression | script | inline script |
-f | file | file | path to script file |
-n | quiet ¦ silent | output only via the p command | |
-i | in-place | inplace edit | |
-i | in-place | .bkp | inplace edit, saves old version with the .bkp extension |
-E ¦ -r | regexp-extended | enables extended regex, instead of default posix | |
-u | unbuffered | flushes output more often | |
-z | null-data | separate by NUL characters | |
-s | separate | consider files as separate | |
sandbox | disable e/r/w commands | ||
posix | disable GNU extensions | ||
debug | annotate execution | ||
follow-symlinks | when doing (-i)nplace editing |
language
#!/bin/sed -f s/Hello/Hell/g
- reads text, line by line, into a temporary buffer called
pattern space
- each line read starts a
cycle
- there is a special buffer called
hold space
used by some commands to hold and accumulate text between cycles - check out
man sed
or the more completeinfo sed
script
- the "body of a loop" that iterates through lines
each line of a script is a pattern-action pair (aka a conditional statement)
[address]command # single command or address { cmd1; cmd2; } # multiple, cannot have a space before ";"
operations
- made of commands
- applied over the pattern space
- by default, after the operations runs
- sed outputs the pattern space
- and begins the cycle again with the next line
addresses
mnemo | applied to | |
---|---|---|
empty | all lines | |
N | line | line N (of each file) |
addr! | not | inverses address match |
N,M | range | from N upto M |
N~S | stepped | from N upto infinity, with steps of size S |
N,+L | length | from N upto N+L |
$ | last | last line |
regex | match | lines that match regex |
- line numbers start at 1(one)
- can mix-up line number and regex
- aregex
- supports arbitrary characters as delimitators, with a backslash for the left one
- \:aregex:
commands
- there are 25 commands
- might take an additional (1 or 2)
address
- use {} to group different commands to the same OR different address
- can separate commands with either
- new lines
- cmd1;cmd2
- -e cmd2 -e cmd2
name | description | |
---|---|---|
q [CODE] | quit | stop processing lines, exit with given exit code |
z | zap | empties the pattern space |
d | delete | the pattern space |
D | delete | only the first line from the pattern space, and run again |
n | next | reads next line into the pattern space AND prints its old value |
N | next | appends next line into the pattern space in a new line |
p | the pattern space | |
P | the first line on the pattern space | |
= | prints the current line number plus a new line | |
y/src/dst/ | (tr)ansliterates src chars for dst chars | |
l | list | list the pattern space unambigously, nice for debugging |
e [CMD] | execute | returns shell output after executing given shell CMD |
r FILE | reads | from given filepath |
w FILE | writes | to given filepath |
b LABEL | branch | jump to given tag, to the end of script if none given |
t LABEL | test branch | jump to given tag, IF previous substitution succeded |
T LABEL | test branch | jump to given tag, IF previous substitution failed |
a STR | append | string after current pattern space |
i STR | insert | string before current pattern space |
c STR | change | replaces current pattern space with given argument |
s/p/r/f | substitute | /pattern/replacement/flags |
uses address for pattern if missing | ||
replacement: "&" pattern matched, \N where N is the N-match group | ||
flags: [w FILE,g,p,I,NUMBEROFMATCH] | ||
hk | ||
h | hold | copy pattern -> hold |
H | hold | append \npattern -> hold |
g | get | copy hold -> pattern |
G | get | append \nhold -> pattern |
x | exchange | aka swap content between hold space and pattern space |
snippets
flag | description | |
---|---|---|
p | prints every line twice | |
p | -n | prints every line |
1p | -n | prints first line |
$p | -n | prints last line |
1,3p | -n | prints lines 1 through 3 |
20,$p | -n | prints from line 20 to end |
#,$p | -n | remove before comment (#) |
=;n | interleaves printing line number, every 2 numbers (1,3..) and each line | |
$= | -n | prints the number of lines (slow?) |
$a 8.8.8.8 google.com | -i /etc/hosts | appends ip/hostname at the end |
1i #Managed by sed | -i /etc/hosts | inserts before line 1, a comment |
$d | -i /etc/hosts | deletes last line |
2d | delete line 2 | |
1,10d | remove the first 10 lines | |
/^ /d | filters out lines starting with space | |
/^ *$/d | filters out lines containing only spaces | |
50,$d | deletes from line 50 to the end | |
/needle/d | deletes lines containing "needle" | |
1,/^$/d | deletes from 1st line to the first blank line | |
/^(#¦$)/d | -E | remove comments and empty lines |
/^#/d;/^$/d | remove comments and empty lines | |
/^\s*(#¦$)/d | -E | remove comments, indentend comments, and empty lines |
---!s/–/\\(em/g | on all lines that do not have 3(-), replace 2(-) | |
s/.*/Hello/;q | reads 1st line of input and prints "Hello" | |
s/needle//g | deletes "needle" from lines | |
s/.$// | dos2unix, aka CRLF to LF | |
/ant/s/needle//g | delete needle on lines containing "ant" |
remove the last 15 lines of a file
https://x.com/cavearr/status/1732554175156834687 https://stackoverflow.com/questions/13380607/how-to-use-sed-to-remove-the-last-n-lines-of-a-file/13380679
$ sox -r 22100 -t u16 -c 1 icerok.raw -n stat -freq 2>&1 | sed -n -e :a -e '1,15!{P;N;D;};N;ba' | gnuplot -p -e 'set logscale x; plot "-" with l'
gotchas
- does NOT follow symlinks for inplace edit by default, unless
--follow-symlinks
codebases
- https://github.com/linguisticmind/search-in-subs
- bach prelude https://github.com/laserbat/bach.sed https://clyp.it/dqgahq1x
- irc bot https://github.com/olsner/smilebot/
- scripts
- debugger
- games
- interpreters