<3 sed

Posted Fri 27 April 2012 17:41 under category tech
Tags:

I wrote a fun sed script today:

sed -E -n -e ':t ; s/(.{21})(.*)/\\bf\{\1\}\n\2/ ; p ; s/\\bf\{(.*)\}\n.*/\1/ ; h ; :q { n ; G ; s/(.{21})(.*)\n\1/\2/ ; tp ; s/(.+)\n.*/\1/ ; bt} ; :p { P ; bq }'

Short, but effective. Can you figure out what it does?

(solution after the break)

Here's an example of what it does:

Sample Input:

000000000000000000000 l0
111111111111111111111 l0.5
111111111111111111111 l0.7
222222222222222222222 l1
222222222222222222222 l2
222222222222222222222 l3
333333333333333333333 l4
333333333333333333333 l5
000000000000000000000 l6

Sample Output:

jbrown% sed -E -n -e ':t ; s/(.{21})(.*)/\\bf\{\1\}\n\2/ ; p ; s/\\bf\{(.*)\}\n.*/\1/ ; h ; :q { n ; G ; s/(.{21})(.*)\n\1/\2/ ; tp ; s/(.+)\n.*/\1/ ; bt} ; :p { P ; bq }' test-in
\bf{000000000000000000000}
 l0
\bf{111111111111111111111}
 l0.5
 l0.7
\bf{222222222222222222222}
 l1
 l2
 l3
\bf{333333333333333333333}
 l4
 l5
\bf{000000000000000000000}
 l6

It's like a uniq -w21 that prefixes every run with the shared prefix. I've had this come up a number of times and tried to solve it with various invocations of uniq, and it kept being annoying. Yes, I am quite aware that this would be a clearer python/perl/whatever script. It was more fun to do in sed, though.


Comments