Den 2011-02-15 21:19 skrev Ralf Wildenhues: > It's a bit of a shame this uses a temp file though. awk should be able > to cope without (but be sure to try old Solaris awk if you go for it).
Ahh, who needs awk? :-) unindent () { sed -n ' x :useit /./{ G h s/\n.*// x /x\(.*\)\n\1/s///p s/.*\n//p d } g /^$/{ p d } s/\([ ]*\).*/x\1/ b useit' } Design is this: at the start of the cycle the hold space holds "x<indent>", so after the <indent> has been found the /./ address matches and everything below that block is ignored. The /./ branch works by first setting up both the pattern and hold to contain "x<indent>\n<input line>" (commands G and h). Then the hold space is restored to contain "x<indent>" (commands s/\n.*// and x). Then any matching indentation is removed, and in case the indentation didn't match, remove the "x<indent>\n" part. And print and restart a new cycle. Below the /./ branch, the indentation is discovered. First a copy of the original input line is made so that it isn't lost. If the input line is empty (the /^$/ branch is taken), just output it and keep looking for the first non-empty line. If the input line is non-empty, remove everything after the last leading whitespace, then prepend x and then go back up and 'useit' as now the pattern space contains "x<indent>" and the hold space holds the input line. One difference with this implementation is that an initial line with only <space>s and <tab>s will be taken as the desired indent to remove, where Stefano's version saw that as an empty line. Too much of a maintenance hassle? You tell me. Cheers, Peter