LinuxQuestions.org
Review your favorite Linux distribution.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices

Reply
 
Search this Thread
Old 07-02-2009, 11:13 AM   #1
don_wombat_73
Member
 
Registered: Sep 2005
Posts: 58

Rep: Reputation: 15
move a line with either sed/awk/perl script


If I had a file that contained the following

test1
test2
test3
test4
test5
test6
test7
test8

and I wanted the end result to be

test1
test2 test3
test4
test5 test6
test7
test8

What would be the best method at accomplishing this?
 
Old 07-02-2009, 12:04 PM   #2
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,823

Rep: Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946
I think you need to be a bit more detailed about your requirements. Do you only need to specify the line numbers to combine, or do you need to match certain text strings? Is it only concatenating sequential lines, or will you have a need to combine lines that are separated by something else?
 
Old 07-02-2009, 12:19 PM   #3
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,823

Rep: Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946
Taking the opening post at face value, you can do this with sed:
Code:
sed  -e '2 {N;s/\n/ /}' -e '5 {N;s/\n/ /}' file.txt
Each expression '-e' will take the line number you specify, combine it with the following line and then replace the newline separating them with a space. You could easily change the line number to a text match if necessary by replacing the line number with /textstring/.

Last edited by David the H.; 07-02-2009 at 12:23 PM.
 
Old 07-02-2009, 01:02 PM   #4
don_wombat_73
Member
 
Registered: Sep 2005
Posts: 58

Original Poster
Rep: Reputation: 15
more specifics....

'Dave the H.' hit the nail on the head. I need it to match the string test2. When I try it with his string, the output is correct. However, when I change it to look for the actual text, it is erroring.

Code:
sed -e 'test2 {N;s/\n/ /}' -e 'test5 {N;s/\n/ /}' junk1
sed: can't find label for jump to `est5'
So I think that the search string might need to be a little different.

The whole point is to search for a string. If the string is found, append the entire line to the end of the previous line.

Sorry for being generic.

Last edited by don_wombat_73; 07-02-2009 at 01:09 PM.
 
Old 07-02-2009, 01:06 PM   #5
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,823

Rep: Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946
Look closer at what I wrote. You need to enclose the text in slashes '/test2/'. This turns it into a regular expression string, which will match if it appears anywhere in the line.

edit:

By the way, "If the string is found, append it to the end of the previous line" is a little more difficult than appending the following line to the one that matches. Which one do you really want?

Last edited by David the H.; 07-02-2009 at 01:09 PM.
 
Old 07-02-2009, 01:22 PM   #6
don_wombat_73
Member
 
Registered: Sep 2005
Posts: 58

Original Poster
Rep: Reputation: 15
Whatever would be the easiest I guess. I need to move lines around so that the end result would be a line looking like

Code:
test2 test3
The example works fine with /textstring/. But lest say the test2 was 'test2foofoofoofoo' and I only wanted to search for test2. Would I use a wildcard? /test2*/

Last edited by don_wombat_73; 07-02-2009 at 01:26 PM.
 
Old 07-02-2009, 02:19 PM   #7
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,823

Rep: Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946
The search will match partial strings. Add a dollar sign to the end of the text string if you don't want it to match a partial string. '/test2$/'

In regular expressions, ^=startofline and $=endofline, so if you wanted to match a whole line you'd need to use '/^test2$/'.

And no, * wouldn't work. Its regex meaning is slightly different from the familiar globbing wildcard. In regex it means "match the preceding character zero or more times". To simulate the * wildcard in regex, you'd have to use ".*", where the period means "any character".

(edit: actually, it looks like * alone does work in this case. I guess sed can handle it either way here.)

There are many good regex tutorials on the net. I recommend reading up on it.

Last edited by David the H.; 07-02-2009 at 02:26 PM.
 
Old 07-02-2009, 02:48 PM   #8
don_wombat_73
Member
 
Registered: Sep 2005
Posts: 58

Original Poster
Rep: Reputation: 15
Thanks 'David the H.'!! I will read up on some of that and see what I can find out.

I appreciate the help!!!
 
Old 07-07-2009, 08:54 AM   #9
don_wombat_73
Member
 
Registered: Sep 2005
Posts: 58

Original Poster
Rep: Reputation: 15
I don't know if you guys want to know, but this is how I got my file working...

sed '
/^host/ {
N
s/\n//
}' file.x > file.y

This did what I needed to do. Thanks for all of your help!
 
Old 07-07-2009, 01:06 PM   #10
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,823

Rep: Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946Reputation: 1946
Glad to see you got it working. I notice two things to be cautious about though.

'/^host/' will match every line that starts with 'host', no matter what else follows.

's/\n//' will simply delete the line-break. The two lines will run together with no space between them.

I hope these are what you want.

BTW, you can now mark your threads as "solved", so that future readers will know you got a satisfactory answer. It's in the thread tools box. You may want to use it to mark this one.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

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
replace a pattern with a line using sed/awk lokeshn05 Linux - Newbie 3 05-06-2009 03:01 PM
again stucked with text processing (sed/awk/perl), copy the line and change rahmathullakm Programming 4 01-19-2009 01:53 PM
extract part of a line with sed or awk alirezan1 Linux - Newbie 2 10-01-2008 09:44 PM
Problem changing line with sed. Should i use AWK? RattleSn@ke Linux - General 7 11-12-2007 01:03 PM
SED, AWK or PERL HELP embsupafly Programming 6 08-20-2005 09:07 PM


All times are GMT -5. The time now is 02:35 AM.

Main Menu
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
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration