0

I want to change the multi-line contain foo2 to be like desired output
foo2 is like an array in multiline, how to change it to be in one line

  • FROM:
$ cat file.txt
foo1=bar1
foo2=('bar10: some text here'
      'bar11: anther text here'
       ...
      'bar: final text here')
foo3=('bar3')
foo=1.2.33

  • TO:
foo1=bar1
foo2="bar10 bar11 .. bar"
foo3=('bar3')
foo=1.2.33
5
  • oki i will remove
    – nextloop
    Commented Oct 8, 2021 at 17:25
  • why would you want to do that? foo2 looks like a good candidate for converting to an associative array (with keys like bar, bar10, bar11, etc and values like "some text here" etc). A space separated string is a poor substitute for an array (and will cause you all sorts of problems and annoyances). It's easy - even in a language like bash - to get a list of all the keys of the array, if that's what you need.
    – cas
    Commented Oct 9, 2021 at 1:30
  • - to install an app that doesn't in Archlinux by Pacman, you must create a file PKGBUILD, this file tells to Pacman how to download, extract, compiled, and install from GitHub or any other site... - void Linux use file called template is similar to PKGBUILD, but with different syntax - I'm trying to convert PKGBUILD to template.
    – nextloop
    Commented Oct 9, 2021 at 5:36
  • If you don't literally have a string that's ... in your real input and .. in your expected output then please edit your question to remove them from your example so we have something we can copy/paste to test with.
    – Ed Morton
    Commented Oct 9, 2021 at 15:00
  • it's doing a good job for me and anyone wants to use awk to substitute multi-line, thank you
    – nextloop
    Commented Oct 9, 2021 at 19:17

2 Answers 2

2

Using any awk in any shell on every Unix box and assuming that ... line in your input and .. string in your output don't literally exist in your real data and are intended to represent text similar to the text around them:

$ cat tst.awk
(val=="") && /.*\047$/ {
    tag = $0
    sub(/=.*/,"",tag)
    val = ""
}
tag != "" {
    split($0,f,/[\047:]/)
    val = (val == "" ? "" : val " ") f[2]
    if ( /\)$/ ) {
        print tag "=\"" val "\""
        tag = ""
    }
    next
}
{ print }

$ awk -f tst.awk file.txt
foo1=bar1
foo2="bar10 bar11 bar"
foo3=('bar3')
foo=1.2.33
2
  • It works, thank you, did you give me a name of a good book for advanced awk learning?
    – nextloop
    Commented Oct 9, 2021 at 19:12
  • 1
    You're welcome. Beginner, advanced and everything in between - Effective AWK Programming, 5th Edition, by Arnold Robbins.
    – Ed Morton
    Commented Oct 9, 2021 at 20:52
1

with sed :

sed -n '/^foo2=(/ba;p;d;:a N;/)$/!ba;s/\n//g;s/  */ /gp' file1

with perl

perl -pe '
    $_ = /[)]$/ ? s/  */ /gr : 
    (substr $_, 0, -1) =~ s/  */ /gr
        if /^foo2=[(]/ .. /[)]$/
' test

or if your perl version doesn't have the r modifier for the substitution:

perl -pe '
    $_ = /[)]$/ ? $_ : substr $_, 0, -1 and s/  */ /g 
        if /^foo2=[(]/ .. /[)]$/
' test

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .