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

Reply via email to