How to get values after an equal sign
I have a file delimited with space and random column ordering as follows:
name=Joan age=42 ip=172.20.1.80 sex=M loc=UK
loc=IR sex=F ip=172.20.1.1 age=32 name=Sandra
I want to extract specific fields (name
, loc
, and ip
) only.
So the result that I'm looking for is as follows:
Joan|UK|172.20.1.80
Sandra|IR|172.20.1.1
bash text-processing
add a comment |
I have a file delimited with space and random column ordering as follows:
name=Joan age=42 ip=172.20.1.80 sex=M loc=UK
loc=IR sex=F ip=172.20.1.1 age=32 name=Sandra
I want to extract specific fields (name
, loc
, and ip
) only.
So the result that I'm looking for is as follows:
Joan|UK|172.20.1.80
Sandra|IR|172.20.1.1
bash text-processing
Similar (if you just replace the space with newline), stackoverflow.com/questions/16571739/…
– michael
Jan 27 at 13:04
@michael Not quite. You need something to detect the different "blocks" then if the input has more that one line.
– PerlDuck
Jan 27 at 13:12
add a comment |
I have a file delimited with space and random column ordering as follows:
name=Joan age=42 ip=172.20.1.80 sex=M loc=UK
loc=IR sex=F ip=172.20.1.1 age=32 name=Sandra
I want to extract specific fields (name
, loc
, and ip
) only.
So the result that I'm looking for is as follows:
Joan|UK|172.20.1.80
Sandra|IR|172.20.1.1
bash text-processing
I have a file delimited with space and random column ordering as follows:
name=Joan age=42 ip=172.20.1.80 sex=M loc=UK
loc=IR sex=F ip=172.20.1.1 age=32 name=Sandra
I want to extract specific fields (name
, loc
, and ip
) only.
So the result that I'm looking for is as follows:
Joan|UK|172.20.1.80
Sandra|IR|172.20.1.1
bash text-processing
bash text-processing
edited Jan 27 at 20:34
Peter Mortensen
1,03721016
1,03721016
asked Jan 27 at 11:32
Ubai salihUbai salih
253
253
Similar (if you just replace the space with newline), stackoverflow.com/questions/16571739/…
– michael
Jan 27 at 13:04
@michael Not quite. You need something to detect the different "blocks" then if the input has more that one line.
– PerlDuck
Jan 27 at 13:12
add a comment |
Similar (if you just replace the space with newline), stackoverflow.com/questions/16571739/…
– michael
Jan 27 at 13:04
@michael Not quite. You need something to detect the different "blocks" then if the input has more that one line.
– PerlDuck
Jan 27 at 13:12
Similar (if you just replace the space with newline), stackoverflow.com/questions/16571739/…
– michael
Jan 27 at 13:04
Similar (if you just replace the space with newline), stackoverflow.com/questions/16571739/…
– michael
Jan 27 at 13:04
@michael Not quite. You need something to detect the different "blocks" then if the input has more that one line.
– PerlDuck
Jan 27 at 13:12
@michael Not quite. You need something to detect the different "blocks" then if the input has more that one line.
– PerlDuck
Jan 27 at 13:12
add a comment |
3 Answers
3
active
oldest
votes
Luckily, your input file has a format the shell understands when it comes to
assigning variables a value: var1=value1 var2=value2
etc. So we can simply
read each line and use the eval
command to evaluate the line.
Put the following into a file, say parse.sh
, do chmod +x parse.sh
and
run it with your input file as a parameter.
Script parse.sh
:
#!/usr/bin/env bash
while read line; do
eval $line;
echo "$name|$loc|$ip"
done < "$1"
exit 0;
File input.txt
:
name=Joan age=42 ip=172.20.1.80 sex=M loc=UK
loc=IR sex=F ip=172.20.1.1 age=32 name=Sandra
Run:
me@ubuntu:~> ./parse.sh input.txt
Joan|UK|172.20.1.80
Sandra|IR|172.20.1.1
Please note that the values must not have a space in them. E.g.
ip=... name=Ubai salih loc=...
would not work and give syntax errors. Also, if the input file would contain a line with a bad_command
that command gets executed because that is how eval
works: it just executes the given string.
just awesome , thank you very much
– Ubai salih
Jan 27 at 12:57
2
Die to the risk if code injection (malicious or accidentally), I might prefer a different solution.
– michael
Jan 27 at 13:06
1
@michael Yes, you are right. I added a note to the answer to mention that. Another possibility would be to split at spaces and then at=
. Or pickname=S+
etc. with a regex. Feel invited to post another approach ;-)
– PerlDuck
Jan 27 at 13:09
1
@michael *Due to the risk *of ... Too late to edit the comment I know, but just wanted to mention the typos in case anyone else is confused.
– wjandrea
Jan 27 at 21:16
Oh goodness, sorry, I just noticed the typo (I blame autocorrect). Code injection is bad, but only on rare occasion lethal.
– michael
Jan 28 at 14:15
add a comment |
FWIW, here's a Python solution like PerlDuck's Bash solution, but not evaluating the input.
#!/usr/bin/env python3
import fileinput
for line in fileinput.input():
record = line.rstrip('n')
d = dict(kv.split('=') for kv in record.split(' '))
print(d['name'], d['loc'], d['ip'], sep='|')
Run:
$ ./parse.py input.txt
Joan|UK|172.20.1.80
Sandra|IR|172.20.1.1
add a comment |
Since the output order that you want is reverse lexical (name > loc > ip) you could select and then reverse sort the fields, then remove the fieldname=
prefixes. For example in Perl:
$ perl -alne '
print join "|", map { s/.*=//r } reverse sort grep { /^(name|loc|ip)=/ } @F
' file
Joan|UK|172.20.1.80
Sandra|IR|172.20.1.1
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "89"
};
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: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
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%2faskubuntu.com%2fquestions%2f1113249%2fhow-to-get-values-after-an-equal-sign%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
Luckily, your input file has a format the shell understands when it comes to
assigning variables a value: var1=value1 var2=value2
etc. So we can simply
read each line and use the eval
command to evaluate the line.
Put the following into a file, say parse.sh
, do chmod +x parse.sh
and
run it with your input file as a parameter.
Script parse.sh
:
#!/usr/bin/env bash
while read line; do
eval $line;
echo "$name|$loc|$ip"
done < "$1"
exit 0;
File input.txt
:
name=Joan age=42 ip=172.20.1.80 sex=M loc=UK
loc=IR sex=F ip=172.20.1.1 age=32 name=Sandra
Run:
me@ubuntu:~> ./parse.sh input.txt
Joan|UK|172.20.1.80
Sandra|IR|172.20.1.1
Please note that the values must not have a space in them. E.g.
ip=... name=Ubai salih loc=...
would not work and give syntax errors. Also, if the input file would contain a line with a bad_command
that command gets executed because that is how eval
works: it just executes the given string.
just awesome , thank you very much
– Ubai salih
Jan 27 at 12:57
2
Die to the risk if code injection (malicious or accidentally), I might prefer a different solution.
– michael
Jan 27 at 13:06
1
@michael Yes, you are right. I added a note to the answer to mention that. Another possibility would be to split at spaces and then at=
. Or pickname=S+
etc. with a regex. Feel invited to post another approach ;-)
– PerlDuck
Jan 27 at 13:09
1
@michael *Due to the risk *of ... Too late to edit the comment I know, but just wanted to mention the typos in case anyone else is confused.
– wjandrea
Jan 27 at 21:16
Oh goodness, sorry, I just noticed the typo (I blame autocorrect). Code injection is bad, but only on rare occasion lethal.
– michael
Jan 28 at 14:15
add a comment |
Luckily, your input file has a format the shell understands when it comes to
assigning variables a value: var1=value1 var2=value2
etc. So we can simply
read each line and use the eval
command to evaluate the line.
Put the following into a file, say parse.sh
, do chmod +x parse.sh
and
run it with your input file as a parameter.
Script parse.sh
:
#!/usr/bin/env bash
while read line; do
eval $line;
echo "$name|$loc|$ip"
done < "$1"
exit 0;
File input.txt
:
name=Joan age=42 ip=172.20.1.80 sex=M loc=UK
loc=IR sex=F ip=172.20.1.1 age=32 name=Sandra
Run:
me@ubuntu:~> ./parse.sh input.txt
Joan|UK|172.20.1.80
Sandra|IR|172.20.1.1
Please note that the values must not have a space in them. E.g.
ip=... name=Ubai salih loc=...
would not work and give syntax errors. Also, if the input file would contain a line with a bad_command
that command gets executed because that is how eval
works: it just executes the given string.
just awesome , thank you very much
– Ubai salih
Jan 27 at 12:57
2
Die to the risk if code injection (malicious or accidentally), I might prefer a different solution.
– michael
Jan 27 at 13:06
1
@michael Yes, you are right. I added a note to the answer to mention that. Another possibility would be to split at spaces and then at=
. Or pickname=S+
etc. with a regex. Feel invited to post another approach ;-)
– PerlDuck
Jan 27 at 13:09
1
@michael *Due to the risk *of ... Too late to edit the comment I know, but just wanted to mention the typos in case anyone else is confused.
– wjandrea
Jan 27 at 21:16
Oh goodness, sorry, I just noticed the typo (I blame autocorrect). Code injection is bad, but only on rare occasion lethal.
– michael
Jan 28 at 14:15
add a comment |
Luckily, your input file has a format the shell understands when it comes to
assigning variables a value: var1=value1 var2=value2
etc. So we can simply
read each line and use the eval
command to evaluate the line.
Put the following into a file, say parse.sh
, do chmod +x parse.sh
and
run it with your input file as a parameter.
Script parse.sh
:
#!/usr/bin/env bash
while read line; do
eval $line;
echo "$name|$loc|$ip"
done < "$1"
exit 0;
File input.txt
:
name=Joan age=42 ip=172.20.1.80 sex=M loc=UK
loc=IR sex=F ip=172.20.1.1 age=32 name=Sandra
Run:
me@ubuntu:~> ./parse.sh input.txt
Joan|UK|172.20.1.80
Sandra|IR|172.20.1.1
Please note that the values must not have a space in them. E.g.
ip=... name=Ubai salih loc=...
would not work and give syntax errors. Also, if the input file would contain a line with a bad_command
that command gets executed because that is how eval
works: it just executes the given string.
Luckily, your input file has a format the shell understands when it comes to
assigning variables a value: var1=value1 var2=value2
etc. So we can simply
read each line and use the eval
command to evaluate the line.
Put the following into a file, say parse.sh
, do chmod +x parse.sh
and
run it with your input file as a parameter.
Script parse.sh
:
#!/usr/bin/env bash
while read line; do
eval $line;
echo "$name|$loc|$ip"
done < "$1"
exit 0;
File input.txt
:
name=Joan age=42 ip=172.20.1.80 sex=M loc=UK
loc=IR sex=F ip=172.20.1.1 age=32 name=Sandra
Run:
me@ubuntu:~> ./parse.sh input.txt
Joan|UK|172.20.1.80
Sandra|IR|172.20.1.1
Please note that the values must not have a space in them. E.g.
ip=... name=Ubai salih loc=...
would not work and give syntax errors. Also, if the input file would contain a line with a bad_command
that command gets executed because that is how eval
works: it just executes the given string.
edited Jan 27 at 13:06
answered Jan 27 at 12:17
PerlDuckPerlDuck
6,73711535
6,73711535
just awesome , thank you very much
– Ubai salih
Jan 27 at 12:57
2
Die to the risk if code injection (malicious or accidentally), I might prefer a different solution.
– michael
Jan 27 at 13:06
1
@michael Yes, you are right. I added a note to the answer to mention that. Another possibility would be to split at spaces and then at=
. Or pickname=S+
etc. with a regex. Feel invited to post another approach ;-)
– PerlDuck
Jan 27 at 13:09
1
@michael *Due to the risk *of ... Too late to edit the comment I know, but just wanted to mention the typos in case anyone else is confused.
– wjandrea
Jan 27 at 21:16
Oh goodness, sorry, I just noticed the typo (I blame autocorrect). Code injection is bad, but only on rare occasion lethal.
– michael
Jan 28 at 14:15
add a comment |
just awesome , thank you very much
– Ubai salih
Jan 27 at 12:57
2
Die to the risk if code injection (malicious or accidentally), I might prefer a different solution.
– michael
Jan 27 at 13:06
1
@michael Yes, you are right. I added a note to the answer to mention that. Another possibility would be to split at spaces and then at=
. Or pickname=S+
etc. with a regex. Feel invited to post another approach ;-)
– PerlDuck
Jan 27 at 13:09
1
@michael *Due to the risk *of ... Too late to edit the comment I know, but just wanted to mention the typos in case anyone else is confused.
– wjandrea
Jan 27 at 21:16
Oh goodness, sorry, I just noticed the typo (I blame autocorrect). Code injection is bad, but only on rare occasion lethal.
– michael
Jan 28 at 14:15
just awesome , thank you very much
– Ubai salih
Jan 27 at 12:57
just awesome , thank you very much
– Ubai salih
Jan 27 at 12:57
2
2
Die to the risk if code injection (malicious or accidentally), I might prefer a different solution.
– michael
Jan 27 at 13:06
Die to the risk if code injection (malicious or accidentally), I might prefer a different solution.
– michael
Jan 27 at 13:06
1
1
@michael Yes, you are right. I added a note to the answer to mention that. Another possibility would be to split at spaces and then at
=
. Or pick name=S+
etc. with a regex. Feel invited to post another approach ;-)– PerlDuck
Jan 27 at 13:09
@michael Yes, you are right. I added a note to the answer to mention that. Another possibility would be to split at spaces and then at
=
. Or pick name=S+
etc. with a regex. Feel invited to post another approach ;-)– PerlDuck
Jan 27 at 13:09
1
1
@michael *Due to the risk *of ... Too late to edit the comment I know, but just wanted to mention the typos in case anyone else is confused.
– wjandrea
Jan 27 at 21:16
@michael *Due to the risk *of ... Too late to edit the comment I know, but just wanted to mention the typos in case anyone else is confused.
– wjandrea
Jan 27 at 21:16
Oh goodness, sorry, I just noticed the typo (I blame autocorrect). Code injection is bad, but only on rare occasion lethal.
– michael
Jan 28 at 14:15
Oh goodness, sorry, I just noticed the typo (I blame autocorrect). Code injection is bad, but only on rare occasion lethal.
– michael
Jan 28 at 14:15
add a comment |
FWIW, here's a Python solution like PerlDuck's Bash solution, but not evaluating the input.
#!/usr/bin/env python3
import fileinput
for line in fileinput.input():
record = line.rstrip('n')
d = dict(kv.split('=') for kv in record.split(' '))
print(d['name'], d['loc'], d['ip'], sep='|')
Run:
$ ./parse.py input.txt
Joan|UK|172.20.1.80
Sandra|IR|172.20.1.1
add a comment |
FWIW, here's a Python solution like PerlDuck's Bash solution, but not evaluating the input.
#!/usr/bin/env python3
import fileinput
for line in fileinput.input():
record = line.rstrip('n')
d = dict(kv.split('=') for kv in record.split(' '))
print(d['name'], d['loc'], d['ip'], sep='|')
Run:
$ ./parse.py input.txt
Joan|UK|172.20.1.80
Sandra|IR|172.20.1.1
add a comment |
FWIW, here's a Python solution like PerlDuck's Bash solution, but not evaluating the input.
#!/usr/bin/env python3
import fileinput
for line in fileinput.input():
record = line.rstrip('n')
d = dict(kv.split('=') for kv in record.split(' '))
print(d['name'], d['loc'], d['ip'], sep='|')
Run:
$ ./parse.py input.txt
Joan|UK|172.20.1.80
Sandra|IR|172.20.1.1
FWIW, here's a Python solution like PerlDuck's Bash solution, but not evaluating the input.
#!/usr/bin/env python3
import fileinput
for line in fileinput.input():
record = line.rstrip('n')
d = dict(kv.split('=') for kv in record.split(' '))
print(d['name'], d['loc'], d['ip'], sep='|')
Run:
$ ./parse.py input.txt
Joan|UK|172.20.1.80
Sandra|IR|172.20.1.1
edited Feb 1 at 14:26
answered Jan 27 at 23:05
wjandreawjandrea
9,21442363
9,21442363
add a comment |
add a comment |
Since the output order that you want is reverse lexical (name > loc > ip) you could select and then reverse sort the fields, then remove the fieldname=
prefixes. For example in Perl:
$ perl -alne '
print join "|", map { s/.*=//r } reverse sort grep { /^(name|loc|ip)=/ } @F
' file
Joan|UK|172.20.1.80
Sandra|IR|172.20.1.1
add a comment |
Since the output order that you want is reverse lexical (name > loc > ip) you could select and then reverse sort the fields, then remove the fieldname=
prefixes. For example in Perl:
$ perl -alne '
print join "|", map { s/.*=//r } reverse sort grep { /^(name|loc|ip)=/ } @F
' file
Joan|UK|172.20.1.80
Sandra|IR|172.20.1.1
add a comment |
Since the output order that you want is reverse lexical (name > loc > ip) you could select and then reverse sort the fields, then remove the fieldname=
prefixes. For example in Perl:
$ perl -alne '
print join "|", map { s/.*=//r } reverse sort grep { /^(name|loc|ip)=/ } @F
' file
Joan|UK|172.20.1.80
Sandra|IR|172.20.1.1
Since the output order that you want is reverse lexical (name > loc > ip) you could select and then reverse sort the fields, then remove the fieldname=
prefixes. For example in Perl:
$ perl -alne '
print join "|", map { s/.*=//r } reverse sort grep { /^(name|loc|ip)=/ } @F
' file
Joan|UK|172.20.1.80
Sandra|IR|172.20.1.1
answered Jan 27 at 12:49
steeldriversteeldriver
68k11111182
68k11111182
add a comment |
add a comment |
Thanks for contributing an answer to Ask Ubuntu!
- 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%2faskubuntu.com%2fquestions%2f1113249%2fhow-to-get-values-after-an-equal-sign%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
Similar (if you just replace the space with newline), stackoverflow.com/questions/16571739/…
– michael
Jan 27 at 13:04
@michael Not quite. You need something to detect the different "blocks" then if the input has more that one line.
– PerlDuck
Jan 27 at 13:12