LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
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 08-17-2018, 07:44 PM   #1
vincix
Senior Member
 
Registered: Feb 2011
Distribution: Ubuntu, Centos
Posts: 1,240

Rep: Reputation: 103Reputation: 103
inserting lines from a file into another file as the nth line


Basically what I'm trying to find out is to see if the following expression can have a file as the input and as the result to be output into another file:
Code:
sed '3~4 i string' file.txt
So instead of "string" I'd like to have lines from a certain file.
Code:
sed -e '4~4 e cat input.txt' file.txt
This doesn't do what I'm expecting it to do. After the 4th line, it inserts the whole "input.txt", and that's it. So I guess I'd need a loop. So I tried:
Code:
for i in input.txt; do sed -e '4~4 e cat $i file.txt'
Which is, of course, even worse, as it's going to insert the whole input.txt after each 4th line.

I also tried this:
Code:
while read line; do sed -e "4~4 i $line" file.txt; done < input.txt
Which inserts the same line (taken at a time) in the whole file, after each 4th line, and then it begins again with the second line from input.txt and so, again, I end up with a huge number of lines.

I'm not sure how I'm supposed to approach this problem.
 
Old 08-17-2018, 10:15 PM   #2
scasey
LQ Veteran
 
Registered: Feb 2013
Location: Tucson, AZ, USA
Distribution: CentOS 7.9.2009
Posts: 5,727

Rep: Reputation: 2211Reputation: 2211Reputation: 2211Reputation: 2211Reputation: 2211Reputation: 2211Reputation: 2211Reputation: 2211Reputation: 2211Reputation: 2211Reputation: 2211
I think we need a better explanation of what you're trying to accomplish.

Best would be to show us the contents (samples of the data) of both files and what you want the final result to be.
Perhaps sed is not the right tool for the job.
 
Old 08-18-2018, 02:42 AM   #3
vincix
Senior Member
 
Registered: Feb 2011
Distribution: Ubuntu, Centos
Posts: 1,240

Original Poster
Rep: Reputation: 103Reputation: 103
The first expression, sed '3~4 i string' file.txt, introduces the string "string" each 4th line, starting with the 3rd line. Instead of "string" I'd like to take the lines from a certain file and introduce them into the second file in the same way (starting with the third line and then adding the lines every 4th line).
First file:
Code:
Warum hast du mich nie gefragt,
worum es in diesem Film geht?
Und warum hab ich es dir eigentlich nie erzählt?
second file (destination):
Code:
1
00:02:44,040 --> 00:02:45,960
Why haven't you ever asked me

2
00:02:46,200 --> 00:02:49,240
what is this film about?

3
00:02:53,720 --> 00:02:58,800
And why haven't I ever told you, anyway?
The merge:
Code:
1
00:02:44,040 --> 00:02:45,960
Warum hast du mich nie gefragt,
Why haven't you ever asked me

2
00:02:46,200 --> 00:02:49,240
worum es in diesem Film geht?
what is this film about?

3
00:02:53,720 --> 00:02:58,800
Und warum hab ich es dir eigentlich nie erzählt?
And why haven't I ever told you, anyway?
 
Old 08-18-2018, 03:10 AM   #4
syg00
LQ Veteran
 
Registered: Aug 2003
Location: Australia
Distribution: Lots ...
Posts: 21,125

Rep: Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120
Wrong tool.
I'd probably use awk as it enables the detection of file change on read, but a shell script to read and keep count of records (or use modulo) then getline from the inserts should be simple enough to test.
 
Old 08-18-2018, 03:13 AM   #5
vincix
Senior Member
 
Registered: Feb 2011
Distribution: Ubuntu, Centos
Posts: 1,240

Original Poster
Rep: Reputation: 103Reputation: 103
It seems weird that I can do it so easily with a simple string with sed, but I can't do it when the input are several lines from a file Not that I have anything against awk, I'm trying to progress in that respect too, but I'm also trying to understand more advanced sed editing.
 
Old 08-18-2018, 03:45 AM   #6
syg00
LQ Veteran
 
Registered: Aug 2003
Location: Australia
Distribution: Lots ...
Posts: 21,125

Rep: Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120
sed is a stream editor, as I think I've pointed out before. It has a hold buffer and looping constructs, but doesn't have the logic capabilities sometimes needed.
A shifting spanner does lot of jobs, but sometimes you really need a hammer.
 
Old 08-18-2018, 03:45 AM   #7
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,830

Rep: Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308
you need to understand how sed works at all. And you will understand better why is it not really suitable for this task (first of all because sed cannot read input from one file and put lines into the other. sed is a stream editor, it works on a single stream [only]). Learning advanced sed editing is a good idea, but will not help you in this specific case (although there can be a pure sed solution).
You ought to try another tool which can handle this situation. awk/perl/python/c/java or whatever you prefer.
 
Old 08-19-2018, 10:28 AM   #8
Kenhelm
Member
 
Registered: Mar 2008
Location: N. W. England
Distribution: Mandriva
Posts: 360

Rep: Reputation: 170Reputation: 170
GNU sed has the 'R' command. It queues a line of a file to be read and inserted into the output stream at the end of the current cycle, or when the next input line is read. Because the inserted lines don't enter the pattern space they can't be edited or manipulated.
https://www.gnu.org/software/sed/man...-Commands.html
Code:
sed '2~4 R file1.txt' file2.txt

1
00:02:44,040 --> 00:02:45,960
Warum hast du mich nie gefragt,
Why haven't you ever asked me

2
00:02:46,200 --> 00:02:49,240
worum es in diesem Film geht?
what is this film about?

3
00:02:53,720 --> 00:02:58,800
Und warum hab ich es dir eigentlich nie erzählt?
And why haven 't I ever told you, anyway?
 
3 members found this post helpful.
Old 08-19-2018, 01:03 PM   #9
MadeInGermany
Senior Member
 
Registered: Dec 2011
Location: Simplicity
Posts: 2,789

Rep: Reputation: 1201Reputation: 1201Reputation: 1201Reputation: 1201Reputation: 1201Reputation: 1201Reputation: 1201Reputation: 1201Reputation: 1201
Even the (standard-)shell is quite good for this.
Code:
#!/bin/sh
cnt=1
while IFS= read f1
do
  echo "$f1"
  if [ $((cnt+=1)) -eq 4 ]
  then
    cnt=1
    IFS= read f2 <&3
    echo "$f2"
  fi
done <file.txt 3<insert.txt
The while-done block is fed from file.txt via stdin (file descriptor 0) and from insert.txt via file descriptor 3 (1 and 2 are reserved for stdout and stderr).

Last edited by MadeInGermany; 08-19-2018 at 02:26 PM.
 
1 members found this post helpful.
Old 08-19-2018, 01:45 PM   #10
vincix
Senior Member
 
Registered: Feb 2011
Distribution: Ubuntu, Centos
Posts: 1,240

Original Poster
Rep: Reputation: 103Reputation: 103
Great! Thank you, Kenhelm, for showing me such an easy solution with sed.
That doesn't mean that I'm not taking into consideration what syg00 and pan64 said. They do have a point.

It's nice to know that I can also do it with bash. I'll have to digest it first A script you suggested on another thread I understood after 6-7 months ) Not that it was too complicated, but it was good homework. I kept returning to it from time to time until I kind of got it
 
Old 08-19-2018, 06:28 PM   #11
syg00
LQ Veteran
 
Registered: Aug 2003
Location: Australia
Distribution: Lots ...
Posts: 21,125

Rep: Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120
Quote:
Originally Posted by vincix View Post
Great! Thank you, Kenhelm, for showing me such an easy solution with sed.
Indeed. I'm sure I've glossed over that at some time and thought "what the hell would I use that for ..."
 
Old 08-20-2018, 10:07 AM   #12
danielbmartin
Senior Member
 
Registered: Apr 2010
Location: Apex, NC, USA
Distribution: Mint 17.3
Posts: 1,881

Rep: Reputation: 660Reputation: 660Reputation: 660Reputation: 660Reputation: 660Reputation: 660
With InFile1 ...
Code:
Warum hast du mich nie gefragt,
worum es in diesem Film geht?
Und warum hab ich es dir eigentlich nie erzählt?
... and InFile2 ...
Code:
1
00:02:44,040 --> 00:02:45,960
Why haven't you ever asked me

2
00:02:46,200 --> 00:02:49,240
what is this film about?

3
00:02:53,720 --> 00:02:58,800
And why haven't I ever told you, anyway?
... this sed ...
Code:
sed '2~4 R $InFile1' $InFile2 > $OutFile
... produced this OutFile ...
Code:
1
00:02:44,040 --> 00:02:45,960
Why haven't you ever asked me

2
00:02:46,200 --> 00:02:49,240
what is this film about?

3
00:02:53,720 --> 00:02:58,800
And why haven't I ever told you, anyway?
This result does not match that shown in post #8.

Please advise.

Daniel B. Martin

.
 
Old 08-20-2018, 10:19 AM   #13
vincix
Senior Member
 
Registered: Feb 2011
Distribution: Ubuntu, Centos
Posts: 1,240

Original Poster
Rep: Reputation: 103Reputation: 103
Well, yeah, because $InFile1 is going to be interpreted literally under the simple quotes. Why are you using variables in the first place, anyhow? Just use the files themselves, like in post #8. I'm not sure how sed handles bash variables. As far as I can tell, sed doesn't find anything in $InFile1, so there's nothing to output.
 
2 members found this post helpful.
Old 08-20-2018, 10:20 AM   #14
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,830

Rep: Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308
you ought to learn about quotation....
Also try to use set -xv to see what's really happening during execution.
Also you can try www.shellcheck.net to catch problems.

And if you still not found:
between 'single quotes' the variables are not evaluated, so sed will see (and wanted to use as filename) $InFile1 as is.
 
1 members found this post helpful.
Old 08-20-2018, 10:36 AM   #15
danielbmartin
Senior Member
 
Registered: Apr 2010
Location: Apex, NC, USA
Distribution: Mint 17.3
Posts: 1,881

Rep: Reputation: 660Reputation: 660Reputation: 660Reputation: 660Reputation: 660Reputation: 660
Thank you, pan64 and vincix, for the correction. Though I ought to know better, I often get tripped up with quotation.

Daniel B. Martin

.
 
  


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
replacing nth line of a file with a new line containing different sets of values kbashyal Linux - Newbie 8 10-08-2017 01:24 PM
How to read and print nth multiple lines from a file bal_nair Programming 5 11-08-2013 12:11 AM
print lines form nth line to mth line which fulfill specific condition cristalp Programming 4 11-07-2011 07:39 AM
Inserting first two lines into a file ZAMO Programming 2 09-04-2008 08:20 AM
nth line of a file in perl kadhan Programming 1 02-20-2008 11:15 AM

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

All times are GMT -5. The time now is 03:51 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