Delete line in file... Simple Bash troubles again!
Delete line in file... Simple Bash troubles again!
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.
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.
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:
(Note you have to use tabs not spaces at the start of the lines)
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
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.
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.
so, if you want to replace an entire line with sed, try:
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.
Code: Select all
sed -e '/Reboot/c\
New line contents' /etc/.jwmrc
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.
- Dougal
- Posts: 2502
- Joined: Wed 19 Oct 2005, 13:06
- Location: Hell more grotesque than any medieval woodcut
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.
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
Some say your nose
Some say your toes
But I think it's your mind
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.
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.
More sed stuff
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:
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:
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)
To print all the lines after that line, try
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)
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#'
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
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
Code: Select all
sed -n '/Reboot/,$p' /etc/.jwmrc
(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)
Finding extra ` chars
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.
That can help sometimes.
- Dougal
- Posts: 2502
- Joined: Wed 19 Oct 2005, 13:06
- Location: Hell more grotesque than any medieval woodcut
Re: More sed stuff
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...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)
What's the ugliest part of your body?
Some say your nose
Some say your toes
But I think it's your mind
Some say your nose
Some say your toes
But I think it's your mind
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.
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.
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]
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]
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
You can just use
and save yourself a process, along with its CPU time and memory.
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
Code: Select all
<file complicated pipeline
- Dougal
- Posts: 2502
- Joined: Wed 19 Oct 2005, 13:06
- Location: Hell more grotesque than any medieval woodcut
Oops... I hope you're not slaving away for nothing.sunburnt wrote:It's a JWM Start menu editor, add, move, delete menus & menu items, etc.
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
Some say your nose
Some say your toes
But I think it's your mind