Delete line in file... Simple Bash troubles again!

Using applications, configuring, problems
Post Reply
Message
Author
User avatar
sunburnt
Posts: 5090
Joined: Wed 08 Jun 2005, 23:11
Location: Arizona, U.S.A.

Delete line in file... Simple Bash troubles again!

#1 Post by sunburnt »

I tried: cat /etc/.jwmrc |sed "s#^.*Reboot.*$##"
But it errors.

I tried: cat /etc/.jwmrc |sed "#^.*Reboot.*$#,#</JWM>#d"
It should print out the first part of the file up to the line with "Reboot" in it.

Then I tried:
LINE="`cat /etc/.jwmrc |grep "Reboot"`"
cat /etc/.jwmrc |sed "#$LINE#,#</JWM>#d"

Same result as the second one.
This is the preferred way to do it, print the file up to the selected line, then print after the line.
Then I can use the same pair of commands for both remove & add.

This is for an editor utility for the .jwmrc file, that adds or removes a line.
The lines in .jwmrc have file paths that have the "/" character.
Feeding sed with variables doesn't allow for escaping them.
Using "#" for the sed command seems to have solved that error.

wom_bat
Posts: 14
Joined: Thu 30 Nov 2006, 00:38

#2 Post by wom_bat »

Why use cat and sed for this? Almost any use of cat with a single argument is an unnecessary extra process.

Why not just
grep -v 'Reboot' /etc/.jwmrc
to get everything except the `Reboot' line?


Or if you want to delete the first line containing `Reboot' in-place use ed:

Code: Select all

ed /etc/.jwmrc <<-EOF
         /Reboot/d
         w
         q
EOF
(Note you have to use tabs not spaces at the start of the lines)

wom_bat
Posts: 14
Joined: Thu 30 Nov 2006, 00:38

#3 Post by wom_bat »

(Oh, if you do want to use sed, the way to go is
sed '/Reboot/d' /etc/.jwmrc

But if this is the only transformation you want to make, fgrep -v
is faster.

fgrep -v 'Reboot' /etc/.jwmrc

User avatar
sunburnt
Posts: 5090
Joined: Wed 08 Jun 2005, 23:11
Location: Arizona, U.S.A.

#4 Post by sunburnt »

Thanks wom_bat; I found that experimenting in the last few minutes.

But I also need to add (insert) a line to the file at a chosen line.
That's why printing the first half of the file up to the chosen line would work good.
Then add the new line to the file, & then print the chosen line & everything after.

I typed "ed" & error: file not found, I'm still using Puppy-1.
I use a variable to feed the commands because accessing the file is slow & HD intensive.
Accessing a file in the /var dir. isn't bad though, because it's in memory anyway.

The commands from: HANDY ONE-LINERS FOR SED

This should work for the last part of the "add" function.
# print all of file EXCEPT section between 2 regular expressions
sed '/Iowa/,/Montana/d'

This should work for the first part of both & last part of "remove".
# print section of file between two regular expressions (inclusive)
sed -n '/Iowa/,/Montana/p' # case sensitive

It's a simple common thing to insert & remove a line from a file!
And here I thought I was getting half way good at Bash.

wom_bat
Posts: 14
Joined: Thu 30 Nov 2006, 00:38

#5 Post by wom_bat »

so, if you want to replace an entire line with sed, try:

Code: Select all

sed -e '/Reboot/c\
New line contents' /etc/.jwmrc
This will replace the line containing Reboot with New line contents.
The only tricky bit is that you must escape any embedded newlines with a backslash.

Of course there are other ways to do it, but this avoids having to do hairy quoting.

User avatar
MU
Posts: 13649
Joined: Wed 24 Aug 2005, 16:52
Location: Karlsruhe, Germany
Contact:

#6 Post by MU »

I get an error with
cat /root/.jwmrc |sed "s#^.*Reboot.*$##"

but not with:
cat /root/.jwmrc |sed "s/^.*Reboot.*$//"

Mark

User avatar
Dougal
Posts: 2502
Joined: Wed 19 Oct 2005, 13:06
Location: Hell more grotesque than any medieval woodcut

#7 Post by Dougal »

Wom_bat: are you the same "wombat" that was here before?? You seem like a pretty knowledgeable fella! Welcome.

Sunburnt: I've been using this for a long time: you can use sed with a "newline" embedded into the "new" string of a substitute command. I've been using this to "leach" onto menu entries to add new ones at a specific place (but please note that it's dangerous, since the menu entries might change with different Puppy versions!).
Try looking at the dotpup with my improved remaster script (look at the file add.sh).
You can also look at my new Xkb config scripts, where I sometimes add a new line, using the one above it and having a "\n" between them.

Please note that sed seems to not work perfectly… when I created my XFCE dotpup I used this methos to add a line to .xinitrc but when I tested it I couldn't get back into X!
What happened was that for some reason the script didn't work properly when the dotpup was installed and xinitrc ended up empty!
I tried running the script again afterwards and it worked fine! So what I ended up doing was have a loop that performed the sed command, then grep-ed to see if xinitrc was ok. If it was: break, if not: restore original (always make a backup…) and try again.
The script tries that 3 times before giving up.
What's the ugliest part of your body?
Some say your nose
Some say your toes
But I think it's your mind

User avatar
sunburnt
Posts: 5090
Joined: Wed 08 Jun 2005, 23:11
Location: Arizona, U.S.A.

#8 Post by sunburnt »

Thanks guys, I've got it inserting a test line in Xterm.

Dougal; I've added a menu version check to avoid newer .jwmrc files.
When it's verified that the newer version will work, then it can be added.
Q; Do you know of any changes to ANY .jwmrc files newer than Puppy-1?

Now the script gives: unexpected EOF while looking for matching ``'
This is common... I've checked & rechecked & can't find a missing or extra "`".
I did: cat ./jwm-menu |grep '`'
This gives all the lines in the file with the character "`", making it easier.
For the heck of it I added a "`", then it errored with: missing " character.


I've searched for a Bash syntax checker several times, but to no avail.
A little while back I started writing one, but my limited ability stopped me.
Problem is I can't figure out a way to count the given characters in a line.
Doing it line by line would point out lines with an odd number of given characters.
This wouldn't always be correct, but it sure would be better than nothing.

Anyway I've checked it at least 10 times, sooo I'm going to do something else now.

wom_bat
Posts: 14
Joined: Thu 30 Nov 2006, 00:38

More sed stuff

#9 Post by wom_bat »

Some basic sed rules:

A sed command has the form
address[,addresscommand

If the address is empty, the command applies to every line.

An address can be a search string.

A command can be a list of commands in braces.

So you can do:

Code: Select all

  sed '/Reboot/s#.*Reboot.*#New contents of line#'
An address can be a regular expression in slashes, or a line number
And you can have two to restrict what you do, It's all pretty powerful

So, to append a line after a the first line containing `Reboot' do:

Code: Select all

sed '/Reboot/a\
New line contents' filename
To put the line before the line, use i (insert) instead of a

And you can group commands.

Your original requirement, to print all the lines up to a line containing a pattern, is easy (but may lead to broken pipe warnings if sed is taking its input freom a pipe)

Code: Select all

sed '/Reboot/q' /etc/.jwmrc
To print all the lines after that line, try

Code: Select all

sed -n '/Reboot/,$p' /etc/.jwmrc
But in general it's best to process a file once rather than make multiple pases over it -- it's faster.

(And no, I've never particpated in this forum before. But I have been using Unix since 1979, so should know what I'm talking about)

wom_bat
Posts: 14
Joined: Thu 30 Nov 2006, 00:38

Finding extra ` chars

#10 Post by wom_bat »

Try running with sh -vn to see how the shell is parsing things, and sh -x to see what it's doing.

That can help sometimes.

User avatar
Dougal
Posts: 2502
Joined: Wed 19 Oct 2005, 13:06
Location: Hell more grotesque than any medieval woodcut

Re: More sed stuff

#11 Post by Dougal »

wom_bat wrote:(And no, I've never particpated in this forum before. But I have been using Unix since 1979, so should know what I'm talking about)
well, mate, welcome aboard! It's good to have someone who knows what he's doing around here... I think GuestToo is probably the only experienced Linux user around here, the rest of us just stumble along...
What's the ugliest part of your body?
Some say your nose
Some say your toes
But I think it's your mind

GuestToo
Puppy Master
Posts: 4083
Joined: Wed 04 May 2005, 18:11

#12 Post by GuestToo »

i just stumble along like anyone else ... Puppy does have a few pecularities that experienced users of other Linux systems might not be aware of (often caused by Busybox), so not all of the knowledge from working with other systems is directly applicable to Puppy ... but most of it is

Braden
Posts: 69
Joined: Fri 22 Sep 2006, 20:39
Location: Waterloo, Ontario, Canada

#13 Post by Braden »

cat source_file | perl -ne 'print unless /Reboot/;'
to remove.

To add, if order doesn't matter, just
echo 'The Line I want to Insert' >> target_file

If order does matter, you need a way to recognize the line you want to insert a line after, and then you can use this one:
cat source_file | perl -ne 'print; print "Insert this line\n" if /After the line containing this text/;'

Perl is installed stock on Puppy. (props to Barry for that, made this Perl hacker very pleased to see it even in a small distro)
Way less painful for twiddling text than sed and awk tend to be, in simple one-line form or complex script form.

If your goal is to flip between a pair of files, just have two versions and change the target of a symlink between them with the script.

User avatar
sunburnt
Posts: 5090
Joined: Wed 08 Jun 2005, 23:11
Location: Arizona, U.S.A.

#14 Post by sunburnt »

Hi Braden;
It's a JWM Start menu editor, add, move, delete menus & menu items, etc.
Much like a command line equivilent of FireFox's "Manage Bookmarks".
Puppy needs one of these for each of it's most popular window managers.
Those would be: JWM, IceWM, & XFCE, I think KDE & Gnome have their own.[/img]

User avatar
sunburnt
Posts: 5090
Joined: Wed 08 Jun 2005, 23:11
Location: Arizona, U.S.A.

#15 Post by sunburnt »

Got another sed anomaly:

Why doesn't this give just the first character instead of the whole line twice?
# echo "123" |sed '/^./p'
123
123

This should delete the first character, instead it returns nothing.
echo "123" |sed '/^./d'

This deletes the first character.
echo "123" |sed 's/^.//'
23

wom_bat
Posts: 14
Joined: Thu 30 Nov 2006, 00:38

#16 Post by wom_bat »

The default action is to print the line after any substitutions, changes, etc., have been made.

So if you add a `p' you end up printing the line twice.

If you want to print only the lines that you modify, use the -n flag.

Oh, and please avoid

Code: Select all

cat file | complicated pipeline
You can just use

Code: Select all

<file complicated pipeline
and save yourself a process, along with its CPU time and memory.

User avatar
Dougal
Posts: 2502
Joined: Wed 19 Oct 2005, 13:06
Location: Hell more grotesque than any medieval woodcut

#17 Post by Dougal »

sunburnt wrote:It's a JWM Start menu editor, add, move, delete menus & menu items, etc.
Oops... I hope you're not slaving away for nothing.
It seemed to me like a JWM menu-editor would be easier to do with Puppybasic, so I asked plinej about it and he said he'd look into it.
so there is a chance of him posting something one of these days...
What's the ugliest part of your body?
Some say your nose
Some say your toes
But I think it's your mind

Post Reply