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 08-05-2012, 03:25 PM   #1
android70
LQ Newbie
 
Registered: Aug 2012
Posts: 3

Rep: Reputation: Disabled
Bash command


Hi all,

I have a file that has the follow data

#cat file.txt

+2012_01
ferrari-honda-chevrolet
audi-bmw
mercedes
+2012_02
google-android
yahoo
twitter
+2012_03
ubuntu
fedora
suse

I want a command ou script that saves the output to other file like this:

+2012_01
ferrari-honda-chevrolet audi-bmwmercedes
+2012_02
google-androidyahootwitter
+2012_03
ubuntufedorasuse

Basically, I just want the lines that don't start with "+" to merge in one line

Thanks in advanced
 
Old 08-05-2012, 03:39 PM   #2
pixellany
LQ Veteran
 
Registered: Nov 2005
Location: Annapolis, MD
Distribution: Mint
Posts: 17,809

Rep: Reputation: 743Reputation: 743Reputation: 743Reputation: 743Reputation: 743Reputation: 743Reputation: 743
Do you really want them merged with no spaces or punctuation?
Regardless, SED will do it. Go here and read up on SED: http://www.grymoire.com/Unix/Sed.html

Basically, the approach is to read a line into the working register, move to the hold register, and then get the next line and test it for "+". If it does NOT have +, then append it to the hold register. When you come to the next line starting with +, then switch it with the hold register (which now contains all the previous lines), remove the newlines, and then print the combination line.

This seems like it might be homework---but regardless, tell us more about what commands and utilities you are familiar with.
 
Old 08-05-2012, 04:07 PM   #3
android70
LQ Newbie
 
Registered: Aug 2012
Posts: 3

Original Poster
Rep: Reputation: Disabled
I used sed and tr command

sed -n '/+/,+3p' file.txt | tr -d '\n' > NewFile.txt

and the output was something like this

+2012_01ferrari-honda-chevroletaudi-bmwmercedes+2012_02
google-androidyahootwitter+2012_03ubuntufedorasuse

I also used small script like this
Code:
input=File.txt

while 
read line

do 

if [[ $line = *'+'* ]];
then

echo $line >> NewFile.txt
 

elif [[ $linha != *'+'* ]]; then
echo $line | tr -d '\n' >> NewFile.txt

fi

done < $input
 
Old 08-05-2012, 04:22 PM   #4
pixellany
LQ Veteran
 
Registered: Nov 2005
Location: Annapolis, MD
Distribution: Mint
Posts: 17,809

Rep: Reputation: 743Reputation: 743Reputation: 743Reputation: 743Reputation: 743Reputation: 743Reputation: 743
We can see how the first example would not work (tr removes all newlines).

I cannot immediately see how the 2nd example would work...
 
Old 08-05-2012, 08:08 PM   #5
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
Assuming you guarantee 4 lines per entry:
Code:
awk 'ORS=NR%4?" ":"\n"' file
 
Old 08-06-2012, 03:00 AM   #6
android70
LQ Newbie
 
Registered: Aug 2012
Posts: 3

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by grail View Post
Assuming you guarantee 4 lines per entry:
Code:
awk 'ORS=NR%4?" ":"\n"' file
It's almost that. The output was

+2012_01 ferrari-honda-chevrolet audi-bmw mercedes
+2012_02 google-android yahoo twitter
+2012_03 ubuntu fedora suse

but I wanted lines with plus sign in their own line

+2012_01
ferrari-honda-chevrolet audi-bmw mercedes
+2012_02
google-android yahoo twitter
+2012_03
ubuntu fedora suse
 
Old 08-06-2012, 03:08 AM   #7
amboxer21
Member
 
Registered: Mar 2012
Location: New Jersey
Distribution: Gentoo
Posts: 291

Rep: Reputation: Disabled
Quote:
Originally Posted by grail View Post
Assuming you guarantee 4 lines per entry:
Code:
awk 'ORS=NR%4?" ":"\n"' file
Grail can you break down your solution for me please? I was not aware that you could assign NR to ORS like that. Thanks
 
Old 08-06-2012, 09:45 AM   #8
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
@ amboxer21 - the trick here is that we are not assigning anything prior to the '?'. As a combination, ?:, is equivalent to a shortened form of and if/else. Everything after '=' and prior to '?'
is an expression to be tested and when true it will return the portion between '?' and ':', and when false it will return the portion after ':'.

So:

ORS = " ", when NR % 4 is any non-zero value, ie anything not exactly divisible by 4

ORS = "\n", when the above is false, ie. NR == 4 or 8 or 12 ...

@OP - Sorry, misread the output data, try:
Code:
awk 'ORS = (NR%4 && /^[^+]/)?" ":"\n"' file
 
1 members found this post helpful.
Old 08-06-2012, 01:12 PM   #9
pixellany
LQ Veteran
 
Registered: Nov 2005
Location: Annapolis, MD
Distribution: Mint
Posts: 17,809

Rep: Reputation: 743Reputation: 743Reputation: 743Reputation: 743Reputation: 743Reputation: 743Reputation: 743
For completeness, here is a SED solution:
Code:
[mherring@herring_lap play]$ sed -n '$b1;/^+/!{H;b2};:1;x;s/\n/ /g;p;:2' linem

+2012_01 ferrari-honda-chevrolet audi-bmw mercedes
+2012_02 google-android yahoo twitter
+2012_03 ubuntu fedora
[mherring@herring_lap play]$
It has 2 issues to be fixed--the extra line at the beginning, and the deletion of the newline after the date.
 
Old 08-06-2012, 01:26 PM   #10
pixellany
LQ Veteran
 
Registered: Nov 2005
Location: Annapolis, MD
Distribution: Mint
Posts: 17,809

Rep: Reputation: 743Reputation: 743Reputation: 743Reputation: 743Reputation: 743Reputation: 743Reputation: 743
Fixed one of the issues:
Code:
sed -n '$b1;/^+/!{H;b2};:1;x;s/\n/ /2g;p;:2' filename > newfilename
the "2g" tells SED to do the substitution on the 2nd instance and every one after.
 
Old 08-06-2012, 01:33 PM   #11
whizje
Member
 
Registered: Sep 2008
Location: The Netherlands
Distribution: Slackware64 current
Posts: 594

Rep: Reputation: 141Reputation: 141
Not the most beautiful solution but it's get the job done.
Code:
bash-4.2$ cat file.txt |tr "\n" " "| tr "+" "\n+";echo

2012_01 ferrari-honda-chevrolet audi-bmw mercedes 
2012_02 google-android yahoo twitter 
2012_03 ubuntu fedora suse
 
Old 08-06-2012, 01:56 PM   #12
whizje
Member
 
Registered: Sep 2008
Location: The Netherlands
Distribution: Slackware64 current
Posts: 594

Rep: Reputation: 141Reputation: 141
The + disappeared
Code:
bash-4.2$ cat file.txt |tr "\n" " "| sed 's/\+/\n+/g';echo

+2012_01 ferrari-honda-chevrolet audi-bmw mercedes 
+2012_02 google-android yahoo twitter 
+2012_03 ubuntu fedora suse
 
  


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
[SOLVED] How write a literal bash command in a bash file? xeon123 Linux - Newbie 6 11-29-2010 12:05 PM
Bash history delete command from bash itself ashishag Linux - Software 6 05-02-2010 03:39 AM
Bash Command Line Editor, while typing run another command before executing current? gumaheru Linux - General 5 04-13-2010 11:21 AM
[SOLVED] Using a long Bash command including single quotes and pipes in a Bash script antcore Linux - General 9 07-22-2009 11:10 AM
Automatically append another piped command to issued command in bash amateen Programming 1 05-07-2009 06:36 AM

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

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