How to make awk print 3 items in line, The last value if is empty?












0














I have the following text:



Name= Garen
Class= 9C
School= US
Name= Lulu
Class= 4A
Name= Kata
Class= 10D
School= UK


I got the awk cmd below:



awk '$Name ~/Name/ {printf $0;} $Class ~/Class/ {printf $0;} $School ~/School/ {print $0;} ' file.txt


But it outputs in a new line. Like this:



Name= Garen Class= 9C School= US
Name= Lulu Class= 4A Name= Kata Class= 10D School= UK


I want it to output like this :



Name= Garen ,Class= 9C ,School= US
Name= Lulu , Class= 4A ,
Name= Kata ,Class= 10D ,School= UK




if it falls into a situation :



Name= Garen
Class= 9C
Last Name= Wilson
School= US

Name= Lulu
Class= 4A
Last Name= Miller

Name= Kata
Class= 10D
School= UK
Last Name= Thomas


and print:



Name= Garen,Class= 9C,School= US

Name= Lulu,Class= 4A

Name= Kata,Class= 10D,School= UK









share|improve this question





























    0














    I have the following text:



    Name= Garen
    Class= 9C
    School= US
    Name= Lulu
    Class= 4A
    Name= Kata
    Class= 10D
    School= UK


    I got the awk cmd below:



    awk '$Name ~/Name/ {printf $0;} $Class ~/Class/ {printf $0;} $School ~/School/ {print $0;} ' file.txt


    But it outputs in a new line. Like this:



    Name= Garen Class= 9C School= US
    Name= Lulu Class= 4A Name= Kata Class= 10D School= UK


    I want it to output like this :



    Name= Garen ,Class= 9C ,School= US
    Name= Lulu , Class= 4A ,
    Name= Kata ,Class= 10D ,School= UK




    if it falls into a situation :



    Name= Garen
    Class= 9C
    Last Name= Wilson
    School= US

    Name= Lulu
    Class= 4A
    Last Name= Miller

    Name= Kata
    Class= 10D
    School= UK
    Last Name= Thomas


    and print:



    Name= Garen,Class= 9C,School= US

    Name= Lulu,Class= 4A

    Name= Kata,Class= 10D,School= UK









    share|improve this question



























      0












      0








      0







      I have the following text:



      Name= Garen
      Class= 9C
      School= US
      Name= Lulu
      Class= 4A
      Name= Kata
      Class= 10D
      School= UK


      I got the awk cmd below:



      awk '$Name ~/Name/ {printf $0;} $Class ~/Class/ {printf $0;} $School ~/School/ {print $0;} ' file.txt


      But it outputs in a new line. Like this:



      Name= Garen Class= 9C School= US
      Name= Lulu Class= 4A Name= Kata Class= 10D School= UK


      I want it to output like this :



      Name= Garen ,Class= 9C ,School= US
      Name= Lulu , Class= 4A ,
      Name= Kata ,Class= 10D ,School= UK




      if it falls into a situation :



      Name= Garen
      Class= 9C
      Last Name= Wilson
      School= US

      Name= Lulu
      Class= 4A
      Last Name= Miller

      Name= Kata
      Class= 10D
      School= UK
      Last Name= Thomas


      and print:



      Name= Garen,Class= 9C,School= US

      Name= Lulu,Class= 4A

      Name= Kata,Class= 10D,School= UK









      share|improve this question















      I have the following text:



      Name= Garen
      Class= 9C
      School= US
      Name= Lulu
      Class= 4A
      Name= Kata
      Class= 10D
      School= UK


      I got the awk cmd below:



      awk '$Name ~/Name/ {printf $0;} $Class ~/Class/ {printf $0;} $School ~/School/ {print $0;} ' file.txt


      But it outputs in a new line. Like this:



      Name= Garen Class= 9C School= US
      Name= Lulu Class= 4A Name= Kata Class= 10D School= UK


      I want it to output like this :



      Name= Garen ,Class= 9C ,School= US
      Name= Lulu , Class= 4A ,
      Name= Kata ,Class= 10D ,School= UK




      if it falls into a situation :



      Name= Garen
      Class= 9C
      Last Name= Wilson
      School= US

      Name= Lulu
      Class= 4A
      Last Name= Miller

      Name= Kata
      Class= 10D
      School= UK
      Last Name= Thomas


      and print:



      Name= Garen,Class= 9C,School= US

      Name= Lulu,Class= 4A

      Name= Kata,Class= 10D,School= UK






      text-processing awk






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Dec 18 at 7:47

























      asked Dec 17 at 8:36









      thinh luu

      11




      11






















          3 Answers
          3






          active

          oldest

          votes


















          0














          $ awk -v OFS=',' '/^Name/ { if (line != "") print line; line = $0; next } { line = line OFS $0 } END { if (line != "") print line }' file
          Name= Garen,Class= 9C,School= US
          Name= Lulu,Class= 4A
          Name= Kata,Class= 10D,School= UK


          With the updated input in the question, this produces



          Name= Garen,Class= 9C,Last Name= Wilson ,School= US,
          Name= Lulu,Class= 4A,Last Name= Miller,
          Name= Kata,Class= 10D,School= UK,Last Name= Thomas


          If you want to delete the Last Name bit, ignore it explicitly in the awk code:



          $ awk -v OFS=',' '/^Last Name/ { next } /^Name/ { if (line != "") print line; line = $0; next } { line = line OFS $0 } END { if (line != "") print line }' file
          Name= Garen,Class= 9C,School= US,
          Name= Lulu,Class= 4A,
          Name= Kata,Class= 10D,School= UK


          The awk code, as a freestanding awk program with comments:



          BEGIN {
          # Set output field separator to a comma.
          # This can also be done with -v OFS="," on the command line.

          OFS = ","
          }

          /^Last Name/ {
          # Ignore these lines
          next
          }

          /^Name/ {
          # A line starts with "Name".
          # Print the accumulated line and reset the line variable.
          # Continue immediately with next line of input.

          if (line != "")
          print line

          line = $0
          next
          }

          {
          # Accumulate lines in the line variable.
          # Delimit each input data with OFS (a comma).

          line = line OFS $0
          }

          END {
          # Print the last accumulated line.

          if (line != "")
          print line
          }




          With sed (this is an almost identical solution from an answer to another question)



          /^Last Name/ d;             # ignore these lines
          /^Name/ b print_previous; # print previous record
          H; # append this line to hold space
          $ b print_previous; # print previous (last) record
          d; # end processing this line

          :print_previous; # prints a record accumulated in the hold space
          x; # swap in the hold space
          /^$/ d; # if line is empty, delete it
          s/n/,/g; # replace embedded newlines by commas
          # (implicit print)


          Running it:



          $ sed -f script.sed file
          Name= Garen,Class= 9C,School= US
          Name= Lulu,Class= 4A
          Name= Kata,Class= 10D,School= UK





          share|improve this answer























          • I just updated question .
            – thinh luu
            Dec 18 at 7:38










          • @thinhluu I still can't see what's wrong. Sorry. Is it that the Last Name should be removed?
            – Kusalananda
            Dec 18 at 7:38










          • I added variable Last Name but i wanna print do not take Last Name .
            – thinh luu
            Dec 18 at 7:51










          • @thinhluu This is what my latest modifications to the answer does.
            – Kusalananda
            Dec 18 at 7:59










          • Kusalananda Thanks you !
            – thinh luu
            Dec 18 at 9:13



















          0














          You can use awk for this, with the following one-liner, as follow:



          awk -F< '/Name=/ {LGT=length($2);printf("n%s,",substr($2,6,LGT))};
          /Class=/ {LGT=length($2);printf(" %s,",substr($2,6,LGT))};
          /School=/ {LGT=length($2);printf(" %s",substr($2,6,LGT))};
          END {printf("n") }' file.txt


          This solution will print records (i.e. lines in your original file.txt file) in the order in which they appear in file.txt. I added it because it is a (simple) example of how to parse and manipulate strings with awk.



          As in previous answers, file.txt contains:



          <text>Name= Garen</text>
          <text>Class= 9C</text>
          <text>School= US</text>
          <text>Name= Lulu</text>
          <text>Class= 4A</text>
          <text>Name= Kata</text>
          <text>Class= 10D</text>
          <text>School= UK</text>


          Output is:



          Name= Garen, Class= 9C, School= US
          Name= Lulu, Class= 4A
          Name= Kata, Class= 10D, School= UK





          share|improve this answer





























            0















            awk '$Name ~/Name/ {printf $0;} $Class ~/Class/ {printf $0;} $School ~/School/ {print $0;} ' file.txt



            All of $Name, $Class and $School will act exactly as $0, because the Name, Class and School variables are not defined and in awk any undefined variable has the numeric value of 0 and (at least with mawk and gawk) the $ operator will simply convert its argument to a number. Other awk implementations may bail out with an error (the behavior is unspecified by the standard).



            Try this instead:



            awk -F ' *= *' '$1~/^(Name|Class|School)$/{
            if($1 in a){ for(i in a) delete a[i]; comma = ""; printf ORS }
            printf "%s%s= %s", comma, $1, $2; a[$1] = comma = ", "
            }
            END{if(comma) printf ORS}
            ' file.txt

            Name= Garen, Class= 9C, School= US
            Name= Lulu, Class= 4A
            Name= Kata, Class= 10D, School= UK


            The example above tries hard to group key/value tuples no matter what order they're in, and be general (it will work the same on the 1st sample input if the $1~/.../ pattern is removed); but if you know that Name is always first and always present, then everything is much easier:



            awk '/^Name=/{printf "%s%s", nl, $0; nl=ORS}
            /^(Class|School)=/{printf ", %s", $0}
            END{if(nl) printf ORS}' /tmp/file.txt





            share|improve this answer























              Your Answer








              StackExchange.ready(function() {
              var channelOptions = {
              tags: "".split(" "),
              id: "106"
              };
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function() {
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled) {
              StackExchange.using("snippets", function() {
              createEditor();
              });
              }
              else {
              createEditor();
              }
              });

              function createEditor() {
              StackExchange.prepareEditor({
              heartbeatType: 'answer',
              autoActivateHeartbeat: false,
              convertImagesToLinks: false,
              noModals: true,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: null,
              bindNavPrevention: true,
              postfix: "",
              imageUploader: {
              brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
              contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
              allowUrls: true
              },
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              });


              }
              });














              draft saved

              draft discarded


















              StackExchange.ready(
              function () {
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f489431%2fhow-to-make-awk-print-3-items-in-line-the-last-value-if-is-empty%23new-answer', 'question_page');
              }
              );

              Post as a guest















              Required, but never shown

























              3 Answers
              3






              active

              oldest

              votes








              3 Answers
              3






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes









              0














              $ awk -v OFS=',' '/^Name/ { if (line != "") print line; line = $0; next } { line = line OFS $0 } END { if (line != "") print line }' file
              Name= Garen,Class= 9C,School= US
              Name= Lulu,Class= 4A
              Name= Kata,Class= 10D,School= UK


              With the updated input in the question, this produces



              Name= Garen,Class= 9C,Last Name= Wilson ,School= US,
              Name= Lulu,Class= 4A,Last Name= Miller,
              Name= Kata,Class= 10D,School= UK,Last Name= Thomas


              If you want to delete the Last Name bit, ignore it explicitly in the awk code:



              $ awk -v OFS=',' '/^Last Name/ { next } /^Name/ { if (line != "") print line; line = $0; next } { line = line OFS $0 } END { if (line != "") print line }' file
              Name= Garen,Class= 9C,School= US,
              Name= Lulu,Class= 4A,
              Name= Kata,Class= 10D,School= UK


              The awk code, as a freestanding awk program with comments:



              BEGIN {
              # Set output field separator to a comma.
              # This can also be done with -v OFS="," on the command line.

              OFS = ","
              }

              /^Last Name/ {
              # Ignore these lines
              next
              }

              /^Name/ {
              # A line starts with "Name".
              # Print the accumulated line and reset the line variable.
              # Continue immediately with next line of input.

              if (line != "")
              print line

              line = $0
              next
              }

              {
              # Accumulate lines in the line variable.
              # Delimit each input data with OFS (a comma).

              line = line OFS $0
              }

              END {
              # Print the last accumulated line.

              if (line != "")
              print line
              }




              With sed (this is an almost identical solution from an answer to another question)



              /^Last Name/ d;             # ignore these lines
              /^Name/ b print_previous; # print previous record
              H; # append this line to hold space
              $ b print_previous; # print previous (last) record
              d; # end processing this line

              :print_previous; # prints a record accumulated in the hold space
              x; # swap in the hold space
              /^$/ d; # if line is empty, delete it
              s/n/,/g; # replace embedded newlines by commas
              # (implicit print)


              Running it:



              $ sed -f script.sed file
              Name= Garen,Class= 9C,School= US
              Name= Lulu,Class= 4A
              Name= Kata,Class= 10D,School= UK





              share|improve this answer























              • I just updated question .
                – thinh luu
                Dec 18 at 7:38










              • @thinhluu I still can't see what's wrong. Sorry. Is it that the Last Name should be removed?
                – Kusalananda
                Dec 18 at 7:38










              • I added variable Last Name but i wanna print do not take Last Name .
                – thinh luu
                Dec 18 at 7:51










              • @thinhluu This is what my latest modifications to the answer does.
                – Kusalananda
                Dec 18 at 7:59










              • Kusalananda Thanks you !
                – thinh luu
                Dec 18 at 9:13
















              0














              $ awk -v OFS=',' '/^Name/ { if (line != "") print line; line = $0; next } { line = line OFS $0 } END { if (line != "") print line }' file
              Name= Garen,Class= 9C,School= US
              Name= Lulu,Class= 4A
              Name= Kata,Class= 10D,School= UK


              With the updated input in the question, this produces



              Name= Garen,Class= 9C,Last Name= Wilson ,School= US,
              Name= Lulu,Class= 4A,Last Name= Miller,
              Name= Kata,Class= 10D,School= UK,Last Name= Thomas


              If you want to delete the Last Name bit, ignore it explicitly in the awk code:



              $ awk -v OFS=',' '/^Last Name/ { next } /^Name/ { if (line != "") print line; line = $0; next } { line = line OFS $0 } END { if (line != "") print line }' file
              Name= Garen,Class= 9C,School= US,
              Name= Lulu,Class= 4A,
              Name= Kata,Class= 10D,School= UK


              The awk code, as a freestanding awk program with comments:



              BEGIN {
              # Set output field separator to a comma.
              # This can also be done with -v OFS="," on the command line.

              OFS = ","
              }

              /^Last Name/ {
              # Ignore these lines
              next
              }

              /^Name/ {
              # A line starts with "Name".
              # Print the accumulated line and reset the line variable.
              # Continue immediately with next line of input.

              if (line != "")
              print line

              line = $0
              next
              }

              {
              # Accumulate lines in the line variable.
              # Delimit each input data with OFS (a comma).

              line = line OFS $0
              }

              END {
              # Print the last accumulated line.

              if (line != "")
              print line
              }




              With sed (this is an almost identical solution from an answer to another question)



              /^Last Name/ d;             # ignore these lines
              /^Name/ b print_previous; # print previous record
              H; # append this line to hold space
              $ b print_previous; # print previous (last) record
              d; # end processing this line

              :print_previous; # prints a record accumulated in the hold space
              x; # swap in the hold space
              /^$/ d; # if line is empty, delete it
              s/n/,/g; # replace embedded newlines by commas
              # (implicit print)


              Running it:



              $ sed -f script.sed file
              Name= Garen,Class= 9C,School= US
              Name= Lulu,Class= 4A
              Name= Kata,Class= 10D,School= UK





              share|improve this answer























              • I just updated question .
                – thinh luu
                Dec 18 at 7:38










              • @thinhluu I still can't see what's wrong. Sorry. Is it that the Last Name should be removed?
                – Kusalananda
                Dec 18 at 7:38










              • I added variable Last Name but i wanna print do not take Last Name .
                – thinh luu
                Dec 18 at 7:51










              • @thinhluu This is what my latest modifications to the answer does.
                – Kusalananda
                Dec 18 at 7:59










              • Kusalananda Thanks you !
                – thinh luu
                Dec 18 at 9:13














              0












              0








              0






              $ awk -v OFS=',' '/^Name/ { if (line != "") print line; line = $0; next } { line = line OFS $0 } END { if (line != "") print line }' file
              Name= Garen,Class= 9C,School= US
              Name= Lulu,Class= 4A
              Name= Kata,Class= 10D,School= UK


              With the updated input in the question, this produces



              Name= Garen,Class= 9C,Last Name= Wilson ,School= US,
              Name= Lulu,Class= 4A,Last Name= Miller,
              Name= Kata,Class= 10D,School= UK,Last Name= Thomas


              If you want to delete the Last Name bit, ignore it explicitly in the awk code:



              $ awk -v OFS=',' '/^Last Name/ { next } /^Name/ { if (line != "") print line; line = $0; next } { line = line OFS $0 } END { if (line != "") print line }' file
              Name= Garen,Class= 9C,School= US,
              Name= Lulu,Class= 4A,
              Name= Kata,Class= 10D,School= UK


              The awk code, as a freestanding awk program with comments:



              BEGIN {
              # Set output field separator to a comma.
              # This can also be done with -v OFS="," on the command line.

              OFS = ","
              }

              /^Last Name/ {
              # Ignore these lines
              next
              }

              /^Name/ {
              # A line starts with "Name".
              # Print the accumulated line and reset the line variable.
              # Continue immediately with next line of input.

              if (line != "")
              print line

              line = $0
              next
              }

              {
              # Accumulate lines in the line variable.
              # Delimit each input data with OFS (a comma).

              line = line OFS $0
              }

              END {
              # Print the last accumulated line.

              if (line != "")
              print line
              }




              With sed (this is an almost identical solution from an answer to another question)



              /^Last Name/ d;             # ignore these lines
              /^Name/ b print_previous; # print previous record
              H; # append this line to hold space
              $ b print_previous; # print previous (last) record
              d; # end processing this line

              :print_previous; # prints a record accumulated in the hold space
              x; # swap in the hold space
              /^$/ d; # if line is empty, delete it
              s/n/,/g; # replace embedded newlines by commas
              # (implicit print)


              Running it:



              $ sed -f script.sed file
              Name= Garen,Class= 9C,School= US
              Name= Lulu,Class= 4A
              Name= Kata,Class= 10D,School= UK





              share|improve this answer














              $ awk -v OFS=',' '/^Name/ { if (line != "") print line; line = $0; next } { line = line OFS $0 } END { if (line != "") print line }' file
              Name= Garen,Class= 9C,School= US
              Name= Lulu,Class= 4A
              Name= Kata,Class= 10D,School= UK


              With the updated input in the question, this produces



              Name= Garen,Class= 9C,Last Name= Wilson ,School= US,
              Name= Lulu,Class= 4A,Last Name= Miller,
              Name= Kata,Class= 10D,School= UK,Last Name= Thomas


              If you want to delete the Last Name bit, ignore it explicitly in the awk code:



              $ awk -v OFS=',' '/^Last Name/ { next } /^Name/ { if (line != "") print line; line = $0; next } { line = line OFS $0 } END { if (line != "") print line }' file
              Name= Garen,Class= 9C,School= US,
              Name= Lulu,Class= 4A,
              Name= Kata,Class= 10D,School= UK


              The awk code, as a freestanding awk program with comments:



              BEGIN {
              # Set output field separator to a comma.
              # This can also be done with -v OFS="," on the command line.

              OFS = ","
              }

              /^Last Name/ {
              # Ignore these lines
              next
              }

              /^Name/ {
              # A line starts with "Name".
              # Print the accumulated line and reset the line variable.
              # Continue immediately with next line of input.

              if (line != "")
              print line

              line = $0
              next
              }

              {
              # Accumulate lines in the line variable.
              # Delimit each input data with OFS (a comma).

              line = line OFS $0
              }

              END {
              # Print the last accumulated line.

              if (line != "")
              print line
              }




              With sed (this is an almost identical solution from an answer to another question)



              /^Last Name/ d;             # ignore these lines
              /^Name/ b print_previous; # print previous record
              H; # append this line to hold space
              $ b print_previous; # print previous (last) record
              d; # end processing this line

              :print_previous; # prints a record accumulated in the hold space
              x; # swap in the hold space
              /^$/ d; # if line is empty, delete it
              s/n/,/g; # replace embedded newlines by commas
              # (implicit print)


              Running it:



              $ sed -f script.sed file
              Name= Garen,Class= 9C,School= US
              Name= Lulu,Class= 4A
              Name= Kata,Class= 10D,School= UK






              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Dec 18 at 7:51

























              answered Dec 18 at 5:51









              Kusalananda

              121k16229372




              121k16229372












              • I just updated question .
                – thinh luu
                Dec 18 at 7:38










              • @thinhluu I still can't see what's wrong. Sorry. Is it that the Last Name should be removed?
                – Kusalananda
                Dec 18 at 7:38










              • I added variable Last Name but i wanna print do not take Last Name .
                – thinh luu
                Dec 18 at 7:51










              • @thinhluu This is what my latest modifications to the answer does.
                – Kusalananda
                Dec 18 at 7:59










              • Kusalananda Thanks you !
                – thinh luu
                Dec 18 at 9:13


















              • I just updated question .
                – thinh luu
                Dec 18 at 7:38










              • @thinhluu I still can't see what's wrong. Sorry. Is it that the Last Name should be removed?
                – Kusalananda
                Dec 18 at 7:38










              • I added variable Last Name but i wanna print do not take Last Name .
                – thinh luu
                Dec 18 at 7:51










              • @thinhluu This is what my latest modifications to the answer does.
                – Kusalananda
                Dec 18 at 7:59










              • Kusalananda Thanks you !
                – thinh luu
                Dec 18 at 9:13
















              I just updated question .
              – thinh luu
              Dec 18 at 7:38




              I just updated question .
              – thinh luu
              Dec 18 at 7:38












              @thinhluu I still can't see what's wrong. Sorry. Is it that the Last Name should be removed?
              – Kusalananda
              Dec 18 at 7:38




              @thinhluu I still can't see what's wrong. Sorry. Is it that the Last Name should be removed?
              – Kusalananda
              Dec 18 at 7:38












              I added variable Last Name but i wanna print do not take Last Name .
              – thinh luu
              Dec 18 at 7:51




              I added variable Last Name but i wanna print do not take Last Name .
              – thinh luu
              Dec 18 at 7:51












              @thinhluu This is what my latest modifications to the answer does.
              – Kusalananda
              Dec 18 at 7:59




              @thinhluu This is what my latest modifications to the answer does.
              – Kusalananda
              Dec 18 at 7:59












              Kusalananda Thanks you !
              – thinh luu
              Dec 18 at 9:13




              Kusalananda Thanks you !
              – thinh luu
              Dec 18 at 9:13













              0














              You can use awk for this, with the following one-liner, as follow:



              awk -F< '/Name=/ {LGT=length($2);printf("n%s,",substr($2,6,LGT))};
              /Class=/ {LGT=length($2);printf(" %s,",substr($2,6,LGT))};
              /School=/ {LGT=length($2);printf(" %s",substr($2,6,LGT))};
              END {printf("n") }' file.txt


              This solution will print records (i.e. lines in your original file.txt file) in the order in which they appear in file.txt. I added it because it is a (simple) example of how to parse and manipulate strings with awk.



              As in previous answers, file.txt contains:



              <text>Name= Garen</text>
              <text>Class= 9C</text>
              <text>School= US</text>
              <text>Name= Lulu</text>
              <text>Class= 4A</text>
              <text>Name= Kata</text>
              <text>Class= 10D</text>
              <text>School= UK</text>


              Output is:



              Name= Garen, Class= 9C, School= US
              Name= Lulu, Class= 4A
              Name= Kata, Class= 10D, School= UK





              share|improve this answer


























                0














                You can use awk for this, with the following one-liner, as follow:



                awk -F< '/Name=/ {LGT=length($2);printf("n%s,",substr($2,6,LGT))};
                /Class=/ {LGT=length($2);printf(" %s,",substr($2,6,LGT))};
                /School=/ {LGT=length($2);printf(" %s",substr($2,6,LGT))};
                END {printf("n") }' file.txt


                This solution will print records (i.e. lines in your original file.txt file) in the order in which they appear in file.txt. I added it because it is a (simple) example of how to parse and manipulate strings with awk.



                As in previous answers, file.txt contains:



                <text>Name= Garen</text>
                <text>Class= 9C</text>
                <text>School= US</text>
                <text>Name= Lulu</text>
                <text>Class= 4A</text>
                <text>Name= Kata</text>
                <text>Class= 10D</text>
                <text>School= UK</text>


                Output is:



                Name= Garen, Class= 9C, School= US
                Name= Lulu, Class= 4A
                Name= Kata, Class= 10D, School= UK





                share|improve this answer
























                  0












                  0








                  0






                  You can use awk for this, with the following one-liner, as follow:



                  awk -F< '/Name=/ {LGT=length($2);printf("n%s,",substr($2,6,LGT))};
                  /Class=/ {LGT=length($2);printf(" %s,",substr($2,6,LGT))};
                  /School=/ {LGT=length($2);printf(" %s",substr($2,6,LGT))};
                  END {printf("n") }' file.txt


                  This solution will print records (i.e. lines in your original file.txt file) in the order in which they appear in file.txt. I added it because it is a (simple) example of how to parse and manipulate strings with awk.



                  As in previous answers, file.txt contains:



                  <text>Name= Garen</text>
                  <text>Class= 9C</text>
                  <text>School= US</text>
                  <text>Name= Lulu</text>
                  <text>Class= 4A</text>
                  <text>Name= Kata</text>
                  <text>Class= 10D</text>
                  <text>School= UK</text>


                  Output is:



                  Name= Garen, Class= 9C, School= US
                  Name= Lulu, Class= 4A
                  Name= Kata, Class= 10D, School= UK





                  share|improve this answer












                  You can use awk for this, with the following one-liner, as follow:



                  awk -F< '/Name=/ {LGT=length($2);printf("n%s,",substr($2,6,LGT))};
                  /Class=/ {LGT=length($2);printf(" %s,",substr($2,6,LGT))};
                  /School=/ {LGT=length($2);printf(" %s",substr($2,6,LGT))};
                  END {printf("n") }' file.txt


                  This solution will print records (i.e. lines in your original file.txt file) in the order in which they appear in file.txt. I added it because it is a (simple) example of how to parse and manipulate strings with awk.



                  As in previous answers, file.txt contains:



                  <text>Name= Garen</text>
                  <text>Class= 9C</text>
                  <text>School= US</text>
                  <text>Name= Lulu</text>
                  <text>Class= 4A</text>
                  <text>Name= Kata</text>
                  <text>Class= 10D</text>
                  <text>School= UK</text>


                  Output is:



                  Name= Garen, Class= 9C, School= US
                  Name= Lulu, Class= 4A
                  Name= Kata, Class= 10D, School= UK






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Dec 18 at 8:18









                  Cbhihe

                  2981316




                  2981316























                      0















                      awk '$Name ~/Name/ {printf $0;} $Class ~/Class/ {printf $0;} $School ~/School/ {print $0;} ' file.txt



                      All of $Name, $Class and $School will act exactly as $0, because the Name, Class and School variables are not defined and in awk any undefined variable has the numeric value of 0 and (at least with mawk and gawk) the $ operator will simply convert its argument to a number. Other awk implementations may bail out with an error (the behavior is unspecified by the standard).



                      Try this instead:



                      awk -F ' *= *' '$1~/^(Name|Class|School)$/{
                      if($1 in a){ for(i in a) delete a[i]; comma = ""; printf ORS }
                      printf "%s%s= %s", comma, $1, $2; a[$1] = comma = ", "
                      }
                      END{if(comma) printf ORS}
                      ' file.txt

                      Name= Garen, Class= 9C, School= US
                      Name= Lulu, Class= 4A
                      Name= Kata, Class= 10D, School= UK


                      The example above tries hard to group key/value tuples no matter what order they're in, and be general (it will work the same on the 1st sample input if the $1~/.../ pattern is removed); but if you know that Name is always first and always present, then everything is much easier:



                      awk '/^Name=/{printf "%s%s", nl, $0; nl=ORS}
                      /^(Class|School)=/{printf ", %s", $0}
                      END{if(nl) printf ORS}' /tmp/file.txt





                      share|improve this answer




























                        0















                        awk '$Name ~/Name/ {printf $0;} $Class ~/Class/ {printf $0;} $School ~/School/ {print $0;} ' file.txt



                        All of $Name, $Class and $School will act exactly as $0, because the Name, Class and School variables are not defined and in awk any undefined variable has the numeric value of 0 and (at least with mawk and gawk) the $ operator will simply convert its argument to a number. Other awk implementations may bail out with an error (the behavior is unspecified by the standard).



                        Try this instead:



                        awk -F ' *= *' '$1~/^(Name|Class|School)$/{
                        if($1 in a){ for(i in a) delete a[i]; comma = ""; printf ORS }
                        printf "%s%s= %s", comma, $1, $2; a[$1] = comma = ", "
                        }
                        END{if(comma) printf ORS}
                        ' file.txt

                        Name= Garen, Class= 9C, School= US
                        Name= Lulu, Class= 4A
                        Name= Kata, Class= 10D, School= UK


                        The example above tries hard to group key/value tuples no matter what order they're in, and be general (it will work the same on the 1st sample input if the $1~/.../ pattern is removed); but if you know that Name is always first and always present, then everything is much easier:



                        awk '/^Name=/{printf "%s%s", nl, $0; nl=ORS}
                        /^(Class|School)=/{printf ", %s", $0}
                        END{if(nl) printf ORS}' /tmp/file.txt





                        share|improve this answer


























                          0












                          0








                          0







                          awk '$Name ~/Name/ {printf $0;} $Class ~/Class/ {printf $0;} $School ~/School/ {print $0;} ' file.txt



                          All of $Name, $Class and $School will act exactly as $0, because the Name, Class and School variables are not defined and in awk any undefined variable has the numeric value of 0 and (at least with mawk and gawk) the $ operator will simply convert its argument to a number. Other awk implementations may bail out with an error (the behavior is unspecified by the standard).



                          Try this instead:



                          awk -F ' *= *' '$1~/^(Name|Class|School)$/{
                          if($1 in a){ for(i in a) delete a[i]; comma = ""; printf ORS }
                          printf "%s%s= %s", comma, $1, $2; a[$1] = comma = ", "
                          }
                          END{if(comma) printf ORS}
                          ' file.txt

                          Name= Garen, Class= 9C, School= US
                          Name= Lulu, Class= 4A
                          Name= Kata, Class= 10D, School= UK


                          The example above tries hard to group key/value tuples no matter what order they're in, and be general (it will work the same on the 1st sample input if the $1~/.../ pattern is removed); but if you know that Name is always first and always present, then everything is much easier:



                          awk '/^Name=/{printf "%s%s", nl, $0; nl=ORS}
                          /^(Class|School)=/{printf ", %s", $0}
                          END{if(nl) printf ORS}' /tmp/file.txt





                          share|improve this answer















                          awk '$Name ~/Name/ {printf $0;} $Class ~/Class/ {printf $0;} $School ~/School/ {print $0;} ' file.txt



                          All of $Name, $Class and $School will act exactly as $0, because the Name, Class and School variables are not defined and in awk any undefined variable has the numeric value of 0 and (at least with mawk and gawk) the $ operator will simply convert its argument to a number. Other awk implementations may bail out with an error (the behavior is unspecified by the standard).



                          Try this instead:



                          awk -F ' *= *' '$1~/^(Name|Class|School)$/{
                          if($1 in a){ for(i in a) delete a[i]; comma = ""; printf ORS }
                          printf "%s%s= %s", comma, $1, $2; a[$1] = comma = ", "
                          }
                          END{if(comma) printf ORS}
                          ' file.txt

                          Name= Garen, Class= 9C, School= US
                          Name= Lulu, Class= 4A
                          Name= Kata, Class= 10D, School= UK


                          The example above tries hard to group key/value tuples no matter what order they're in, and be general (it will work the same on the 1st sample input if the $1~/.../ pattern is removed); but if you know that Name is always first and always present, then everything is much easier:



                          awk '/^Name=/{printf "%s%s", nl, $0; nl=ORS}
                          /^(Class|School)=/{printf ", %s", $0}
                          END{if(nl) printf ORS}' /tmp/file.txt






                          share|improve this answer














                          share|improve this answer



                          share|improve this answer








                          edited Dec 18 at 9:11

























                          answered Dec 18 at 3:59









                          mosvy

                          5,9131325




                          5,9131325






























                              draft saved

                              draft discarded




















































                              Thanks for contributing an answer to Unix & Linux Stack Exchange!


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid



                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.


                              To learn more, see our tips on writing great answers.





                              Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                              Please pay close attention to the following guidance:


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid



                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.


                              To learn more, see our tips on writing great answers.




                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function () {
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f489431%2fhow-to-make-awk-print-3-items-in-line-the-last-value-if-is-empty%23new-answer', 'question_page');
                              }
                              );

                              Post as a guest















                              Required, but never shown





















































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown

































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown







                              Popular posts from this blog

                              Morgemoulin

                              Scott Moir

                              Souastre