PDA

View Full Version : newbie regex question -- match and replace a tab?


erictaub
06-28-2002, 06:04 PM
OK, I'm going nuts here. I've been trying to use sed and grep to match/replace tab characters in text files, and I'm having no luck at all. I keep on trying /t, but it just doesn't seem to work, as in:

sed 's/\t/"this is a tab"/'

I'm sure I'm missing something painfully obvious. Any suggestions?

mervTormel
06-28-2002, 06:26 PM
perhaps this will help...

http://www.dbnet.ece.ntua.gr/~george/sed/1liners.txt

if not, then post back here a more explicit explanation of what you're trying to do and what you've tried and perhaps someone can point out your folly.

mervTormel
06-29-2002, 12:11 AM
i see the trouble you're having. here's an example of what does work...

$ cat /etc/crontab | sed 's/ / <tab> /g' | grep "<tab>"
#min <tab> hour <tab> mday <tab> month <tab> wday <tab> user <tab> command
...


note: in the sed above, the tab char between the first s/ / is a real tab, entered
by issuing a ^V^I ( control-V control-I )

pmccann
06-29-2002, 08:23 AM
mT explained: "control-V control-I".

Well that's nice and memorable!! I think that sed and grep/egrep are the only two applications that claim to have support for regexps yet lack this expected mapping. (emacs,python,awk,perl all do, for example.)

Here's a very simple example of substituting for tabs using perl, followed by a little bit of fun along similar lines.

Suppose file testme.txt has some tabs that we wish to replace with " <tab> ", as per mT's example.

perl -pi -e 's/\t/ <tab> /g' testme.txt

*Very* similar to the sed invocation, except for the flags. "-pi" for "*print* every line out after making the changes, while editing *inplace*. That is, no backup file is kept. In reality, a temp file is written, and if all is well (ie the operation succeeds), the temp file is shifted "onto" the original file, giving the appearance of an in-place edit.

In any case, that's pretty mundane, so how about something a little more interesting?

# Double up the lines in a file. If you have the following file...

% less doubles

one
two
three
four
five
six

# Suppose you want to make a tab separated file by "gluing" every second line
# to its predecessor with a tab. This works...

% perl -ne 'chomp; $_.="\t".<>;print $_' doubles

one two
three four
five six

# The entries on a given line are tab separated, though it may not be obvious
# in a broswer window.

# As above, you can edit the file "in-place" by using the -i switch: if you want to
# keep a backup of the original file (in doubles.bak say) you just provide a
# suffix like so

% perl -ni.bak -e 'chomp; $_.="\t".<>;print $_' doubles

# To do things really "in-place" (ie overwrite the file itself) simply omit
# the suffix:

% perl -ni -e 'chomp; $_.="\t".<>;print $_' doubles

# OK: so how about three or more of the things; that is, have the first
# three lines of the file glued together with tabs to produce the first line
# in the new file, and so forth: an extension of the above would be plenty
# ugly. The following is prettier:

% cp doubles.bak doubles # Get back the original file!
% perl -ni -e 'chomp;print; print $.%3?"\t":"\n"' doubles

# You'll find that $. is the line number (or "chunk number" if the chunks that
# you're reading in aren't lines!). Remember that 0 is false, all
# other integers are "true".

Cheers,
Paul