toadi has asked for the wisdom of the Perl Monks concerning the following question:

Well I wouldn't know how to start this.

I got a file where tabs are 8 chars and I want to revert them to 4 chars.
Can this also be done from 4 to 8. And are those spaces then still tabs???



--
My opinions may have changed,
but not the fact that I am right

Replies are listed 'Best First'.
Re: One liner asked... :)
by swiftone (Curate) on Apr 23, 2001 at 19:55 UTC
    I got a file where tabs are 8 chars and I want to revert them to 4 chars.

    Actually, you don't. A tab isn't a certain number of spaces, it's a tab. Various text editors/word processors will represent the tab as a number of spaces. Depending on your settings, they may actually save (X) spaces when you hit tab, rather than save the tab.

    Generally you want to convert tabs to spaces or spaces to tabs. My attempt to do what I think you mean is to either:

    1. Change the configuration on your text editor to set tabs as 4 spaces OR,
    2. do a regex to replace \t with "    "
    Assuming you are interested in the regex, here's a quick-and-dirty try:
    while (<>){ s/\t/ /g; }
    Or to reverse it:
    while (<>){ s/ /\t/g; }
    Note that reversing it isn't an actual reversal....it replaces all sequences of spaces with tabs, even if they weren't originally a tab.
Re: One liner asked... :)
by clemburg (Curate) on Apr 23, 2001 at 20:03 UTC

    Read article 41.04 (p. 754-756) in Unix Power Tools.

    In short:

    • a tab is just one character, the terminal (or printer, or editor, or ... ) does the conversion to spaces
    • the standard Unix utilities "expand" and "unexpand" can be used to convert between tabs and spaces - they are available for Win32 too in the Cygwin package
    • for more detail, read the man pages (or the source :-) ... ) of "expand" and "unexpand"

    Christian Lemburg
    Brainbench MVP for Perl
    http://www.brainbench.com

Re: One liner asked... :)
by mr.nick (Chaplain) on Apr 23, 2001 at 22:23 UTC
    The problem you have with tabs is that they aren't exactly 4 (or 8) spaces. They are upto the next TABSTOP...
    | | | | | | | | | | 1234567890123456789012345678901234567890 this is\ta test this is a test this was\ta test this was a test
    As you can see from the above, the tab character represents a different amount of spaces depending on how close to the next tabstop you are.

    Simple substitution of \t for \s{4} will not work. You must know how many spaces are necessary to reach the next stop.

    Text::Tabs will correctly expand and contract tabs for you.

Re: One liner asked... :)
by premchai21 (Curate) on Apr 23, 2001 at 20:12 UTC
    use vars qw($spaces); my $spaces = " " x shift; while (<>) { s/\t/$spaces/g; # Tabs to spaces. # Perform substitution the other way # for spaces to tabs. print; } #
    It's not one line, though. In golf mode: perl -pe 's/\t/q( )x$n/ge;' replacing $n with some number.

    There's a program somewhere in textutils, in the GNU toolkit, that will do this too.

    Update: Changed according to MeowChow's suggestion.

      You left out a few things. I believe you mean:
      perl -pe 's/\t/q( )x$n/ge' ...
         MeowChow                                   
                     s aamecha.s a..a\u$&owag.print
Re: One liner asked... :)
by arturo (Vicar) on Apr 23, 2001 at 19:57 UTC

    A tab is a single character; the only real issue here is how they get displayed by whatever app you're using. You could write a filter that translates \t to four spaces, I guess, but that would be a *translation* and would assuredly *not* preserve the actual character count of the document.