LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   bash: merge lines if string is found... (https://www.linuxquestions.org/questions/programming-9/bash-merge-lines-if-string-is-found-4175426687/)

masavini 09-11-2012 07:26 AM

bash: merge lines if string is found...
 
i have a file like this:

Code:

ext1
return gigi
ext2
ext4
ext3
return bubu


i need lines starting with "return" to be merged with the previous one:

Code:

ext1 return gigi
ext2
ext4
ext3 return bubu

how to get it with bash?
i tried with:

Code:

sed -e :a -e '$!N; s/\nreturn/ return/; ta' file.txt
but only the first occurrence is processed... can you help me?

thanks!

masavini 09-11-2012 07:33 AM

solved with:
Code:

awk '!/^return/ { if (line) print line; line = $0; next } { sub(/^[ \t]+/, " "); line = line $0 } END { print line }' file.txt

danielbmartin 09-11-2012 08:42 AM

Quote:

Originally Posted by masavini (Post 4777627)
i tried with:
Code:

sed -e :a -e '$!N; s/\nreturn/ return/; ta' file.txt
but only the first occurrence is processed... can you help me?

Your sed was close. Try this ...
Code:

sed -e :a -e '$!N; s/\nreturn/ return/;ta' -e 'P;D' $InFile
Daniel B. Martin

masavini 09-11-2012 09:20 AM

Quote:

Code:

sed -e :a -e '$!N; s/\nreturn/ return/;ta' -e 'P;D' $InFile

you right... it works!
thanks

David the H. 09-11-2012 10:37 AM

FYI, you can read how to do it with sed here:

http://sed.sourceforge.net/sedfaq4.html#s4.26

As you can see, sed isn't really well-designed for multiple-line editing, particularly when it involves moving "back" in the file. The usual workflow for it is one-way.


Incidentally, this can also be done with ed fairly easily.

Code:

ed -s file.txt <<HEREDOC
#start global command list -- find lines starting with "return", move back one, and
#add a space to the end. final backslash means the "g" setting continues to the next command.
g/^return/-1 s/$/ /\'
#join the current line (the one just modified above) with the one after it (end of global command list).
.,+1j
#print the altered buffer to stdout.
%p
#write the buffer back to the original file.
w
#write the buffer to a new file.
w newfile.txt
HEREDOC

I used the heredoc format so I could add comment lines to the script, but any technique that feeds the commands to stdin separated by linefeeds will work. e.g., more compactly:

Code:

printf '%s\n' 'g/^return/-1 s/$/ /\' '.,+1j' '%p' | ed -s file.txt
One limitation, however, that it will error out if "return" ever happens to be the first line of the file.

How to use ed:
http://wiki.bash-hackers.org/howto/edit-ed
http://snap.nlc.dcccd.edu/learn/nlc/ed.html
(also read the info page)

firstfire 09-11-2012 11:29 PM

Ugly solution. REMOVED.

masavini 09-13-2012 12:04 PM

Quote:

Originally Posted by firstfire (Post 4778144)
Ugly solution. REMOVED.

what does it mean?

firstfire 09-13-2012 01:38 PM

Hi.

That means that the solution I suggested in that post (there were 2 of them actually) turned out to be ugly and useless when I reread the thread once again. There are no simple way to remove wrong post, so I replaced its contents with that phrase.


All times are GMT -5. The time now is 07:24 AM.