Writing a script to edit a file in vi

I'm trying to write a script that will perform a substitution and an insert in vi.
here's what I have so far.

vi [filename]
1,$s/&/,/g

I was told to put an escape character in, but I'm not sure what that would be

I would appreciate any help I could get

Thank you.
dizzardAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

RobWMartinCommented:
You mean a line insert?  Like find all &'s replace with , then break the line?

Rob
0
dizzardAuthor Commented:
yes exactly.  If it matters I also have to do a second replace. Where I have to replace all the tabs with nothing.

Thanks again!
0
RobWMartinCommented:
Ok.  Trying to write a script?  Like in open vi with a file and pipe the "script" in through stdin?  You're wanting to do this for more than one file (i.e. more than a one time use)? Do you have to use vi?  Do you have access to vim?

Sorry for all the questions.

Rob
0
Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

RobWMartinCommented:
D@mn, I keep hitting the esc key and having to retype this.  Thank you dizzard, for getting me in vi mode:)

Anyhow, to try something other than answering questions:

in vi

:%s/&/,^M/g

To get the ^M, hold down ctrl and press V, then press return key.  ^V sez escape the next keypress.  Do the same thing with tabs, hitting the tab key instead of the return key.  It will look like this:

:%s/^I//g

Now to pump this into vi automatically:

echo -e ":%s/&/,^V^M/g\n:wq" | vi file

The ^V^M sequence results from three ctrl-V 's and a return.  My shell recognizes ctrl-V as an escape.  If yours doesn't we'll have to explore further.

Rob
0
RobWMartinCommented:
Ooops.  Forgot to add the tabs part:

echo -e ":%s/&/,^V^M/g\n:%s/^V^I//g\n:wg" | vi file

:P
0
dizzardAuthor Commented:
Rob,  When I press the tab key I do not get the "I" instead I get blank space like it inserting a tab.  The first search and replace works great though.

Thanks for your patience.
0
dizzardAuthor Commented:
Rob,  When I press the tab key I do not get the "I" instead I get blank space like it inserting a tab.  The first search and replace works great though.

Thanks for your patience.
0
DineshNeheteCommented:
Dear Dizzard,

Let me first mention what I understood about your question.

1. You want to work in vi
2. You need to replace all '&' by newline
3. You need to replace all tabs by space or NULL.

if this is correct just take this as general rule for seraching and replacing any sequence of characters by other sequence of characters in vi.

There are two ways to do it one is as identified by Rob but I will write it more clearly.

A:
     step 1 -> open the file in vi
     step 2 -> type the following sequence
                    :1,$s/&/^M/g
              expalination of this sequence
              1,$  => search from first line to last line ( 1 for first, $ for last)
              s/ => search instuction string specified in first to '/' characters
             /&/ => the string in first two / is string to be replaced
            /^M/ => the string in next two / is new string
             g      => globally in the file.

           How to generate ^M i.e. newline character.
               For new line press ctrl key and while pressed
               press 'v' key & then 'm' key.
               i.e. ctrl v m
           How to generate ^I i.e. tab character.
                   press  ctrl v Tab
               or press ctrl v i
          your required command will look like
              :1,$s/^I/ /g
           or
              :1,$s/        / /g
              this will replace tab by single space
              :1,$s/^I//g
           or
              :1,$s/       //g
              this will replace tab by null character.

B: This can also be done using other sequence in vi
    step 1 -> open the file in vi
    step 2 -> type the following sequence
                   :g/&/s//^M/g
                   This will search all & in file and replace them by newline ^M
                   first g indicated global in line and second g indicates
                   all the lines.
                   here you have flexibility of handling the search replace
                   within line or across the file.    



Hope this satisfies you.          
0
RobWMartinCommented:
Dinesh,

We got it covered inside vi.  But I think Dizzard wants to run it as a script.  I.e. feed vi the commands and a file to work on.  Dizzard has me stumped on getting a ^I from the shell prompt into vi.

Sorry, Dizzard,  I haven't had a chance to look into again.

Rob
0
ahoffmannCommented:
you cannot script with vi, but awk or sed or perl; perl is the simplest solution (just a few bytes;-)
0
dizzardAuthor Commented:
How would you do substitutions like these with awk or sed?  Really it does work in vi, except I can't find what the "special" character is for a tab on my system.

0
ahoffmannCommented:
there could be a dozent of reasons ...
Assuming that you tried RobWMartin's echo -e example, I'm not wondering if it doesn't work (even it might do), 'cause it depends on the shell, and the used echo command, and the settings of your tty (and probably some more like xmodmap if you're running under X, etc. etc.)

As I said befor, vi is a program for interactive use: vi - view inteactive
for performing such task there are numerous programs: awk, sed, tr, perl, just to name a few.
Best is to go with these, and not struggling with windmills ...
0
DineshNeheteCommented:
Instead of discussing all these let us understand dizzard's requirement.

Is he interested in how to search and replace a pattern in file(s) or his interest is "how to do this using vi"

If the interest is in writting shell script, and tool is not the concern, then there are many  ways as identified by ahoffmann. But if the requirement is using vi as he has identified in his original question then the solution is unique as I mentioned earlier.
0
RobWMartinCommented:
Dizzard,

Ok.  I've had a chance to try something else:

echo -e ":%s/&/,^V^M/g\n:%s/\t//g\n:wg" | vi file

This worked on my system.  The difference is the ^V^I is simply replaced with \t.  Echo subs in the real tab character, and vi accepts it.  I wouldn't try the same thing with the ^V^M (i.e. subbing \n), because vi would read that as premature end of command.  Note: the solution will delete all the tabs.  If you want to replace them (all) with a single space then use s/\t\t*/ /g instead.

Hope this does it!
Rob
0
ahoffmannCommented:
> This worked on my system.
That's possible.
But as I said before, forget about piping commands into vi, you have to beat a lot of dragons. Just an example, simply change
  stty oxtabs
or vice versa
  stty -oxtabs
and the printed examples above may no longer work as described
0
RobWMartinCommented:
Dude, you're talking terminals, I'm talking raw ascii.  Output from echo -e doesn't get translated for tty when it's moving through the pipe.  vi may try, but it is smart enough to recognize that the other end of the pipe is not a tty.  Besides if it satisfies Dizzard, then who cares.

Actually, I agree with you on the ^V^V^V^I being sensitive to tty settings.

Rob
0
ahoffmannCommented:
which echo? (shell, BSD-style, etc.)
Have you really testied all variants? (dude:  I know that I'm very picky ;-)
0
RobWMartinCommented:
Ok, now you're talking shells.  I mentioned in my fourth comment, that there may be shell dependencies.  I totally agree with you, if this were a general purpose effort, with publication in mind.  However, in that case, I certainly wouldn't be wasting time with a vi "script."  If it works in Dizzard's shell, then we're done.  If not, like I've said before, we can pursue something else.

BTW: I don't think you're picky.  It's just obvious that you've got alot of programming/scripting experience under your belt; probably for large, heterogenous installation where thinking it through is vital.  I have to think that way, too, most of the time.  However, I love these little "projects" where you can just glue things together, run it a few times, and then forget about it.  In such cases, I don't worry about the implications of portability.

Later, Dude :)
Rob

0
ahoffmannCommented:
nice comment Rob ;-)
(tty, shell, echo, it all plays together, sometimes, somehow)
BTW, now you're talking ...

probably we should wait for dizzards comments now, instead of chatting
0
dizzardAuthor Commented:
The \t worked perfectly!!!!!!!

Thanks Rob!

Thanks everyone for being so helpful and patient.  I really appreciate all the help.



0
RobWMartinCommented:
You're very welcome.  That's why we're here:)
0
lenlutzCommented:
try this

#gres
THIS=$1
WITH_THAT=$2
shift
shift

for i in $@
do
#echo "working on $i"
ed - $i <<END
1,\$s/${THIS}/${WITH_THAT}/g
w
q
END
done
~

# this will replace DOG with CAT in ALL files (matching arg3)
0
RobWMartinCommented:
Dizzard,

I hate to be a pointmonger, but can you accept one of my comments as answer.  I gather from your comment,

"The \t worked perfectly!!!!!!!

Thanks Rob! "

that my answers satisfied your question.  If you don't take action, the proposed, manual, solution by DineshNahete will be autograded by the system and he will get the points.

Do I sound greedy, or what?  I just wouldn't want you to lose any sleep over this ;)

Rob

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
dizzardAuthor Commented:
Rob's comments helped and solved my question.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Unix OS

From novice to tech pro — start learning today.