LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 12-14-2009, 09:02 AM   #1
Magil
LQ Newbie
 
Registered: Dec 2009
Posts: 12

Rep: Reputation: 0
question about sed


Hello I am trying to copy a few lines from a file using sed. More specifically i want to copy lines 2-8, 10-15, 20-21 from file1 to file 2. I tried the following:

Quote:
sed '2,8p' -n file1 > file 2
This works but adding the other lines doesnt, i tried using
Quote:
sed'2,8p && 10,15p' -n file1 > file2
So im basically asking how to use a logical 'and' using sed, or how to include/exclude certain lines from a file. any suggestions?
 
Old 12-14-2009, 09:08 AM   #2
druuna
LQ Veteran
 
Registered: Sep 2003
Posts: 10,532
Blog Entries: 7

Rep: Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405
Hi,

You can "string" sed statements like this:

sed -ne '2,8p' -e '10,15p' -e '20,21p' infile

The -e options being the key to it all.

Hope this helps.
 
1 members found this post helpful.
Old 12-14-2009, 09:17 AM   #3
Magil
LQ Newbie
 
Registered: Dec 2009
Posts: 12

Original Poster
Rep: Reputation: 0
Thanks a lot works like a charm.
 
Old 12-14-2009, 09:25 AM   #4
ghostdog74
Senior Member
 
Registered: Aug 2006
Posts: 2,697
Blog Entries: 5

Rep: Reputation: 244Reputation: 244Reputation: 244
better to put "q" to quit after line 21.
an alternative with awk
Code:
awk 'NR~/^([2-8]|1[0-5]|2[01])$/{print}NR>21{exit}' file
or with just the shell
Code:
#!/bin/bash
linenum=0
while read -r line
do
  linenum=$((linenum+1))
  case "$linenum" in
     [2-8]|1[0-5]|2[01]) echo "$line";;
     22) break;;
  esac    
done <"file"

Last edited by ghostdog74; 12-14-2009 at 09:26 AM.
 
1 members found this post helpful.
Old 12-14-2009, 09:41 AM   #5
Magil
LQ Newbie
 
Registered: Dec 2009
Posts: 12

Original Poster
Rep: Reputation: 0
ah, using awk does look a bit simpler as i have no clue about the sed variables, thanks!
 
Old 12-14-2009, 10:10 AM   #6
Magil
LQ Newbie
 
Registered: Dec 2009
Posts: 12

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by ghostdog74 View Post
better to put "q" to quit after line 21.
an alternative with awk
Code:
awk 'NR~/^([2-8]|1[0-5]|2[01])$/{print}NR>21{exit}' file
or with just the shell
Code:
#!/bin/bash
linenum=0
while read -r line
do
  linenum=$((linenum+1))
  case "$linenum" in
     [2-8]|1[0-5]|2[01]) echo "$line";;
     22) break;;
  esac    
done <"file"
One more question though, in the shell, how can i declare the input file, it looks like im only writing an output file but no input? thanks.
 
Old 12-14-2009, 07:50 PM   #7
ghostdog74
Senior Member
 
Registered: Aug 2006
Posts: 2,697
Blog Entries: 5

Rep: Reputation: 244Reputation: 244Reputation: 244
did you see the <"file" ?? to declare variables in shell, do it as normal --> filename="file". then use it as $filename
 
Old 12-15-2009, 05:02 AM   #8
Magil
LQ Newbie
 
Registered: Dec 2009
Posts: 12

Original Poster
Rep: Reputation: 0
I am still trying to use the shell version. When i use echo it works like it is supposed to, but when i output to a file it only puts the last line in it. I think that is normal as this program makes one line at a time so the file is being written several times on one line, is there an easy solution for this? thanks.
 
Old 12-15-2009, 05:16 AM   #9
ghostdog74
Senior Member
 
Registered: Aug 2006
Posts: 2,697
Blog Entries: 5

Rep: Reputation: 244Reputation: 244Reputation: 244
show your script then, how you output to file.
 
Old 12-15-2009, 05:27 AM   #10
Magil
LQ Newbie
 
Registered: Dec 2009
Posts: 12

Original Poster
Rep: Reputation: 0
Quote:
#!/bin/sh
linenum=0
while read -r line
do
linenum=$((linenum+1))
file="out1"
case "$linenum" in
[1-9]|1[2-8]|2[2-9]) echo "$line" > "$file";;
22) break;;
esac
done <"4"
Thanks to you i already got this working with sed, but im interested in the use of bash, as i want to become better at this and understand how it works.
 
Old 12-15-2009, 05:28 AM   #11
syg00
LQ Veteran
 
Registered: Aug 2003
Location: Australia
Distribution: Lots ...
Posts: 21,140

Rep: Reputation: 4123Reputation: 4123Reputation: 4123Reputation: 4123Reputation: 4123Reputation: 4123Reputation: 4123Reputation: 4123Reputation: 4123Reputation: 4123Reputation: 4123
This is getting perilously close to being beyond hard-coding the (line) numbers required, and needing a means of feeding them in. I can see a follow-up along the lines of "what if I also wanted lines ..."
Perl becomes a strong contender.
 
Old 12-15-2009, 05:37 AM   #12
ghostdog74
Senior Member
 
Registered: Aug 2006
Posts: 2,697
Blog Entries: 5

Rep: Reputation: 244Reputation: 244Reputation: 244
Quote:
Originally Posted by Magil View Post
Thanks to you i already got this working with sed, but im interested in the use of bash, as i want to become better at this and understand how it works.
a lot of errors in your code. also pls indent your code next time. Is "4" your input file name? if not , change it to your input file name
Code:
#!/bin/sh
linenum=0
file="out1"
while read -r line
do
      linenum=$((linenum+1))
      case "$linenum" in
          [1-9]|1[2-8]|2[2-9]) echo "$line" >> "$file";; #use append mode >> , not >
              22) break;;
      esac
done < "4"
 
Old 12-15-2009, 05:41 AM   #13
ghostdog74
Senior Member
 
Registered: Aug 2006
Posts: 2,697
Blog Entries: 5

Rep: Reputation: 244Reputation: 244Reputation: 244
Quote:
Originally Posted by syg00 View Post
This is getting perilously close to being beyond hard-coding the (line) numbers required, and needing a means of feeding them in. I can see a follow-up along the lines of "what if I also wanted lines ..."
bash is bash, it doesn't have things like $. (line number right??) for Perl, but incrementing counter is common in programming. nothing wrong with that. And what if i wanted other lines? ermm, add them in to the case/esac construct?

Quote:
Perl becomes a strong contender.
i would try awk first, for parsing files and for this case.

Last edited by ghostdog74; 12-15-2009 at 05:42 AM.
 
Old 12-15-2009, 05:51 AM   #14
Magil
LQ Newbie
 
Registered: Dec 2009
Posts: 12

Original Poster
Rep: Reputation: 0
Sorry about the mistakes, im scripting on another machine and am copying the code by hand... Am I to understand that my mistake really was using the > thus copying only what is in the buffer at the time it is executed and overwriting the previous lines? Thanks for the reply.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Another SED question 3saul Linux - Software 2 01-28-2007 12:06 PM
sed question markhod Programming 4 08-03-2006 07:24 AM
[sed] "Advanced" sed question(s) G00fy Programming 2 03-20-2006 12:34 AM
sed question from Ch 6.12 na5m Linux From Scratch 1 02-02-2005 03:36 PM
A question on 'sed' Barbarian Programming 4 04-11-2002 10:19 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 06:53 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration