LinuxQuestions.org
Visit Jeremy's Blog.
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 06-29-2010, 07:02 AM   #1
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,006

Rep: Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191
Insert line of text prior to pattern only once


So I have obviously been looking at this problem for too long now as
I am unable to come up with what I know should be a simple solution,
so here goes:

I have a file like so:
Code:
one
two
three
four
I would like to insert prior to the word "three" all items from this
second file with the following contents:
Code:
four
three
two
one
Now my issue is, and I have been using both sed and awk currently,
that after the second line of the new file is read there will of course now be 2 copies of the word "three" but I would like to only insert the final 2 words, ie "two" and "one" prior to only the first occurrence of the word "three" so final file will look like:
Code:
one
two
four
two
one
three
three
four
So here there is now only one of each word from the second file joined to make the new file.
For simple code I have tried something like the following:
Code:
while read line
do
    awk -v n=$line '!f && /three/{print n;f++}1' file1 > tmp_file
    mv tmp_file file1
done < file2
Now this works but seems very clumsy to me. There is obviously a better sed and / or awk out there.

Look forward to replies
 
Old 06-29-2010, 08:08 AM   #2
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
Does it have to be done in a single operation? You could split file two into two parts, saving lines "four and "three" into one variable or temp file, and "two" and "one" in another. Then you can use two separate sed commands to insert them into file one in the sequence you want. Or some variation of the above. I think that would be much cleaner than trying to finagle everything into a single command.
 
Old 06-29-2010, 09:03 AM   #3
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,006

Original Poster
Rep: Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191
As you probably guessed this is a trivial example to accomplish a larger task. The issue would be that I will eventually be looking at
potentially 50 - 100 files each of these will be coalesced with the original and be searching for potentially different values each time.
The one rule that must remain the same no matter how many files are used is that the insertion should only come prior to the line being searched
for and if there are other copies within file1 then it should stop after the first occurrence.

I hope this is a little clearer.
 
Old 06-29-2010, 10:04 AM   #4
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,780

Rep: Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081
Quote:
Originally Posted by grail View Post
Now this works but seems very clumsy to me. There is obviously a better sed and / or awk out there.
The problem seems awkward, so I think any solution will be too. Here is a sh solution which is a bit longer than yours, but might be considered "better" in that it only uses 1 temp file:
Code:
#!/bin/sh

while read line1 ; do
    while [ "$line1" = three ] && read line2 ; do
        [ "$line2" = three ] && cat
        echo "$line2"
    done < file2
    echo "$line1"
done < file1 > tmp_file
mv tmp_file file1
 
Old 06-29-2010, 10:51 AM   #5
crts
Senior Member
 
Registered: Jan 2010
Posts: 2,020

Rep: Reputation: 757Reputation: 757Reputation: 757Reputation: 757Reputation: 757Reputation: 757Reputation: 757
Hi,

at least with sed I do not see a solution without a temporary file. However, the follwing code produced the same result for your sample data.
Code:
#!/bin/bash

sed -e '/three/ d' reverse > tmp
sed -e '/three/ {
	r tmp
	a \
three\
three
	d
}' forward
It is important that there is exactly one space between the r command and tmp, and nothing after tmp.
 
Old 06-29-2010, 11:10 AM   #6
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,006

Original Poster
Rep: Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191
Hi crts

Thanks for your input The ultimate goal here is this is my attempt to produce dependencies for package management we have spoken of before.
So I am happy to try any given solution My initial thought was recursion but was concerned that if the path grew too deep that bash would
throw a hissy fit.

So I will build on yours and ntubski's solutions to see if they work with a deeper set
 
  


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
Shell Script to Delete part text of a line if pattern matches harsha1980 Programming 36 04-16-2010 03:36 AM
insert text to a file using command line replica88 Linux - Newbie 4 01-28-2010 05:50 PM
vi trick for insert text in between line ufmale Programming 3 05-13-2008 03:01 AM
delete a line containing a pattern and the next line of a text file powah Programming 3 01-31-2007 05:34 PM
Removing Text in a single line starting with one pattern ending on another mgwheeler Programming 13 08-03-2004 04:36 PM

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

All times are GMT -5. The time now is 05:45 PM.

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