How to make awk print 3 items in line, The last value if is empty?
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
add a comment |
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
add a comment |
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
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
text-processing awk
edited Dec 18 at 7:47
asked Dec 17 at 8:36
thinh luu
11
11
add a comment |
add a comment |
3 Answers
3
active
oldest
votes
$ 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
I just updated question .
– thinh luu
Dec 18 at 7:38
@thinhluu I still can't see what's wrong. Sorry. Is it that theLast 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
add a comment |
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
add a comment |
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
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
$ 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
I just updated question .
– thinh luu
Dec 18 at 7:38
@thinhluu I still can't see what's wrong. Sorry. Is it that theLast 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
add a comment |
$ 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
I just updated question .
– thinh luu
Dec 18 at 7:38
@thinhluu I still can't see what's wrong. Sorry. Is it that theLast 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
add a comment |
$ 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
$ 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
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 theLast 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
add a comment |
I just updated question .
– thinh luu
Dec 18 at 7:38
@thinhluu I still can't see what's wrong. Sorry. Is it that theLast 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
add a comment |
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
add a comment |
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
add a comment |
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
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
answered Dec 18 at 8:18
Cbhihe
2981316
2981316
add a comment |
add a comment |
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
add a comment |
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
add a comment |
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
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
edited Dec 18 at 9:11
answered Dec 18 at 3:59
mosvy
5,9131325
5,9131325
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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