LinuxQuestions.org
Help answer threads with 0 replies.
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 05-18-2021, 03:21 PM   #1
PauleeDee
LQ Newbie
 
Registered: May 2021
Posts: 1

Rep: Reputation: Disabled
Appending a list in bash


I have a list in bash that looks like the following.

Quote:
{
name:
address:
phone:
}
{
name:
address:
phone:
}
{
name:
address:
phone:
}
I need to append a comma , after every } except the very last instance as shown below

Quote:
{
name:
address:
phone:
},
{
name:
address:
phone:
},
{
name:
address:
phone:
}
I have been playing with IFS but have not been able to successfully do this or even get close, can anyone advise or assist?
 
Old 05-18-2021, 05:29 PM   #2
TB0ne
LQ Guru
 
Registered: Jul 2003
Location: Birmingham, Alabama
Distribution: SuSE, RedHat, Slack,CentOS
Posts: 23,810

Rep: Reputation: 6974Reputation: 6974Reputation: 6974Reputation: 6974Reputation: 6974Reputation: 6974Reputation: 6974Reputation: 6974Reputation: 6974Reputation: 6974Reputation: 6974
Quote:
Originally Posted by PauleeDee View Post
I have a list in bash that looks like the following.
Code:
{
name:
address:
phone:
}
{
name:
address:
phone:
}
{
name:
address:
phone:
}
I need to append a comma , after every } except the very last instance as shown below
Code:
{
name:
address:
phone:
},
{
name:
address:
phone:
},
{
name:
address:
phone:
}
I have been playing with IFS but have not been able to successfully do this or even get close, can anyone advise or assist?
Happy to help; the first step is you posting what you have done/tried/written so far, and show us what it's doing. There are THOUSANDS of bash scripting guides you can easily find (as you found this forum), with many tutorials and sample code. Read the "Question Guidelines" link in my posting signature.

There are lots of ways to accomplish this, with many different languages and tools. Perl, python, bash, awk, etc., can all do it.
 
Old 05-18-2021, 05:33 PM   #3
danielbmartin
Senior Member
 
Registered: Apr 2010
Location: Apex, NC, USA
Distribution: Mint 17.3
Posts: 1,819

Rep: Reputation: 640Reputation: 640Reputation: 640Reputation: 640Reputation: 640Reputation: 640
sed can do this.

With this InFile ...
Code:
{
name:
address:
phone:
}
{
name:
address:
phone:
}
{
name:
address:
phone:
}
... this sed ...
Code:
sed '$!s/$/,/'  $InFile >$OutFile
... produced this OutFile ...
Code:
{,
name:,
address:,
phone:,
},
{,
name:,
address:,
phone:,
},
{,
name:,
address:,
phone:,
}
Daniel B. Martin

.
 
Old 05-18-2021, 08:25 PM   #4
sundialsvcs
LQ Guru
 
Registered: Feb 2004
Location: SE Tennessee, USA
Distribution: Gentoo, LFS
Posts: 9,140
Blog Entries: 4

Rep: Reputation: 3227Reputation: 3227Reputation: 3227Reputation: 3227Reputation: 3227Reputation: 3227Reputation: 3227Reputation: 3227Reputation: 3227Reputation: 3227Reputation: 3227
But also: "the #!shebang facility is a wonderful thing!"

When placed as the first line of any "shell command" file, this specifies which full-featured script programming language(!) should be used to process it. The shell silently forks a copy of the specified interpreter and hands the remaining file to it. The end-user is none the wiser, but you certainly are!

So far as I am aware, only "the Korn shell" (ksh) ever attempted to embed a "serious" programming language directly into itself. The native scripting capabilities of bash are, quite frankly, something that I almost never use.

Last edited by sundialsvcs; 05-18-2021 at 08:27 PM.
 
Old 05-19-2021, 07:36 AM   #5
shruggy
Senior Member
 
Registered: Mar 2020
Posts: 2,321

Rep: Reputation: Disabled
Quote:
Originally Posted by danielbmartin View Post
Code:
sed '$!s/$/,/'  $InFile >$OutFile
I guess what the OP wants is rather
Code:
sed '$!s/}/&,/'
 
1 members found this post helpful.
Old 05-19-2021, 08:54 PM   #6
mimorek
Member
 
Registered: Feb 2013
Distribution: Debian (jessie)
Posts: 42

Rep: Reputation: Disabled
I just started learning awk.
This one also works if the last } is not on the last line of the file.

Code:
tac thelist.txt | awk '/}/ { if ( X++ ){ sub(/}/, "},") }; print; next } {print}' | tac
 
Old 05-20-2021, 01:22 AM   #7
shruggy
Senior Member
 
Registered: Mar 2020
Posts: 2,321

Rep: Reputation: Disabled
The same without tac:
Code:
awk -vRS=} '
  { a[i++]=$0 }
  END{
    for(j=0;i-j>2;j++) printf "%s},", a[j]
    print a[j]"}"
  }' thelist.txt
Or
Code:
awk 'NR>1{print x}!/}/{x=$0}/}/{x=$0","}END{print}' thelist.txt

Last edited by shruggy; 05-20-2021 at 01:55 AM.
 
Old 05-22-2021, 06:54 AM   #8
MadeInGermany
Senior Member
 
Registered: Dec 2011
Location: Simplicity
Posts: 1,741

Rep: Reputation: 790Reputation: 790Reputation: 790Reputation: 790Reputation: 790Reputation: 790Reputation: 790
Another one (just buffering the lines with a "}")
Code:
awk '
  {
    if (f) { print buf ","; f=0 }
    if (/[}]/) { buf=$0; f=1 }
    else print
  }
  END { if (f) print buf }
' thelist.txt
 
1 members found this post helpful.
Old 05-22-2021, 11:50 AM   #9
shruggy
Senior Member
 
Registered: Mar 2020
Posts: 2,321

Rep: Reputation: Disabled
@MadeInGermany. If there are lines in the file after the last }, your code will print comma after the last closing brace anyway, so the END block can be simplified to END{print}. As this only works if } is on the last line, there is no advantage over sed solution. I guess it's the most compact awk solution though. Rewritten as a one-liner that would be
Code:
awk 'f{print x",";f=0}f=/}/{x=$0}!f;END{print}' thelist.txt
Yet another possibility that also not allows extra lines after the last closing brace is
Code:
awk '{printf"%s",d$0;d=RS}/}/{d=","d}END{print""}' thelist.txt

Last edited by shruggy; 05-22-2021 at 01:16 PM.
 
Old 05-22-2021, 12:57 PM   #10
mimorek
Member
 
Registered: Feb 2013
Distribution: Debian (jessie)
Posts: 42

Rep: Reputation: Disabled
If I take the following as thelist.txt
Code:
before
before
before
{
name:
address:
phone:
}
{
name:
address:
phone:
}
after
after
after
then this command cuts off the end of the input.
Quote:
Originally Posted by shruggy View Post
The same without tac:
Code:
awk -vRS=} '
  { a[i++]=$0 }
  END{
    for(j=0;i-j>2;j++) printf "%s},", a[j]
    print a[j]"}"
  }' thelist.txt
Code:
$ awk -vRS=} '
  { a[i++]=$0 }
  END{
    for(j=0;i-j>2;j++) printf "%s},", a[j]
    print a[j]"}"
  }' thelist.txt
before
before
before
{
name:
address:
phone:
},
{
name:
address:
phone:
}
And this one places a comma after the last }.
Quote:
Originally Posted by shruggy View Post
Or
Code:
awk 'NR>1{print x}!/}/{x=$0}/}/{x=$0","}END{print}' thelist.txt
Code:
$ awk 'NR>1{print x}!/}/{x=$0}/}/{x=$0","}END{print}' thelist.txt
before
before
before
{
name:
address:
phone:
},
{
name:
address:
phone:
},
after
after
after
 
Old 05-22-2021, 01:15 PM   #11
shruggy
Senior Member
 
Registered: Mar 2020
Posts: 2,321

Rep: Reputation: Disabled
^Yep, you're right. Here is a corrected version
Code:
awk -vRS=} '
  { a[i++]=$0 }
  END{
    for(j=0;i-j>2;j++) printf "%s},", a[j]
    printf "%s", a[j++] RS a[j]
  }' thelist.txt

Last edited by shruggy; 05-22-2021 at 02:11 PM.
 
Old 05-22-2021, 01:25 PM   #12
pan64
LQ Guru
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 16,490

Rep: Reputation: 5532Reputation: 5532Reputation: 5532Reputation: 5532Reputation: 5532Reputation: 5532Reputation: 5532Reputation: 5532Reputation: 5532Reputation: 5532Reputation: 5532
I guess that should be a valid json file (or something similar), but that was not stated.
So the specification is incomplete, and we have no idea if those awk scripts fulfill the real requirements.
 
Old 05-22-2021, 09:01 PM   #13
mimorek
Member
 
Registered: Feb 2013
Distribution: Debian (jessie)
Posts: 42

Rep: Reputation: Disabled
Trying to understand these scripts makes my head spin
 
  


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
E: Type 'sudo' is not known on line 1 in source list /etc/apt/sources.list.d/mono-official.list 221B Linux - Newbie 6 09-07-2017 12:14 PM
Appending matching strings to specific lines (sed/bash) suntzu Programming 18 09-08-2012 03:29 PM
'E:Malformed line 54 in source list /etc/apt/sources.list (dist parse), E:The list of vsssuccess@gmail.com Linux - Desktop 1 11-17-2010 08:17 AM
[SOLVED] Appending file extensions to filenames in bash scripts LadyAnne Linux - Newbie 4 05-18-2010 02:32 AM
Appending Text Files From Bash Script alts Programming 3 11-18-2004 06:36 PM

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

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