Shell script: n related problem to split a straightforward line [closed]

Clash Royale CLAN TAG#URR8PPP
up vote
0
down vote
favorite
That's an shell script snippet:
KVS_VARIABLES=$(awk -F= '!($1 && $2 && NF==2) "cat 1>&2"; next print $1, $2 ' $ENV_FILE_LOCATION)
echo $KVS_VARIABLES
for kv in $KVS_VARIABLES
do
echo $kv
key=$(echo $kv | awk -FS=" " 'print $1')
value=$(echo $kv | awk -FS=" " 'print $2')
echo "key: $key | value: $value"
done
I expect an output like:
key: VAR1 | value: VAL1
...
However, I'm getting that:
VAR1 VAL1 VAR2 VAL2 VAR3 VAL3
VAR1
key: VAR1 | value:
VAL1
key: VAL1 | value:
VAR2
key: VAR2 | value:
VAL2
key: VAL2 | value:
VAR3
key: VAR3 | value:
VAL3
key: VAL3 | value:
EDIT
$ echo "$KVS_VARIABLES" ->
VAR1 VAL1
VAR2 VAL2
VAR3 VAL3
shell-script
closed as off-topic by Jeff Schaller, Kiwy, Zachary Brady, thrig, Rui F Ribeiro Jun 29 at 22:53
This question appears to be off-topic. The users who voted to close gave this specific reason:
- "This question has been posted on multiple sites. Cross-posting is strongly discouraged; see the help center and community FAQ for more information." â Jeff Schaller, Kiwy, Zachary Brady, thrig, Rui F Ribeiro
 |Â
show 1 more comment
up vote
0
down vote
favorite
That's an shell script snippet:
KVS_VARIABLES=$(awk -F= '!($1 && $2 && NF==2) "cat 1>&2"; next print $1, $2 ' $ENV_FILE_LOCATION)
echo $KVS_VARIABLES
for kv in $KVS_VARIABLES
do
echo $kv
key=$(echo $kv | awk -FS=" " 'print $1')
value=$(echo $kv | awk -FS=" " 'print $2')
echo "key: $key | value: $value"
done
I expect an output like:
key: VAR1 | value: VAL1
...
However, I'm getting that:
VAR1 VAL1 VAR2 VAL2 VAR3 VAL3
VAR1
key: VAR1 | value:
VAL1
key: VAL1 | value:
VAR2
key: VAR2 | value:
VAL2
key: VAL2 | value:
VAR3
key: VAR3 | value:
VAL3
key: VAL3 | value:
EDIT
$ echo "$KVS_VARIABLES" ->
VAR1 VAL1
VAR2 VAL2
VAR3 VAL3
shell-script
closed as off-topic by Jeff Schaller, Kiwy, Zachary Brady, thrig, Rui F Ribeiro Jun 29 at 22:53
This question appears to be off-topic. The users who voted to close gave this specific reason:
- "This question has been posted on multiple sites. Cross-posting is strongly discouraged; see the help center and community FAQ for more information." â Jeff Schaller, Kiwy, Zachary Brady, thrig, Rui F Ribeiro
if you use double quotes like this.. then are you getting the one key value in each row ? echo "$KVS_VARIABLES"
â Kamaraj
Jun 28 at 7:58
paste the output of echo "$KVS_VARIABLES" ---> (use double quotes)
â Kamaraj
Jun 28 at 7:59
stackoverflow.com/q/51077172/4957508
â Jeff Schaller
Jun 28 at 10:12
A simpler way to print to stderr from awk:print "some string" > "/dev/stderr"
â glenn jackman
Jun 28 at 11:43
You'll want to read mywiki.wooledge.org/BashFAQ/001: "How can I read a file (data stream, variable) line-by-line (and/or field-by-field)?" The first advice is "Don't try to use "for". Use a while loop and the read command. "
â glenn jackman
Jun 28 at 11:45
 |Â
show 1 more comment
up vote
0
down vote
favorite
up vote
0
down vote
favorite
That's an shell script snippet:
KVS_VARIABLES=$(awk -F= '!($1 && $2 && NF==2) "cat 1>&2"; next print $1, $2 ' $ENV_FILE_LOCATION)
echo $KVS_VARIABLES
for kv in $KVS_VARIABLES
do
echo $kv
key=$(echo $kv | awk -FS=" " 'print $1')
value=$(echo $kv | awk -FS=" " 'print $2')
echo "key: $key | value: $value"
done
I expect an output like:
key: VAR1 | value: VAL1
...
However, I'm getting that:
VAR1 VAL1 VAR2 VAL2 VAR3 VAL3
VAR1
key: VAR1 | value:
VAL1
key: VAL1 | value:
VAR2
key: VAR2 | value:
VAL2
key: VAL2 | value:
VAR3
key: VAR3 | value:
VAL3
key: VAL3 | value:
EDIT
$ echo "$KVS_VARIABLES" ->
VAR1 VAL1
VAR2 VAL2
VAR3 VAL3
shell-script
That's an shell script snippet:
KVS_VARIABLES=$(awk -F= '!($1 && $2 && NF==2) "cat 1>&2"; next print $1, $2 ' $ENV_FILE_LOCATION)
echo $KVS_VARIABLES
for kv in $KVS_VARIABLES
do
echo $kv
key=$(echo $kv | awk -FS=" " 'print $1')
value=$(echo $kv | awk -FS=" " 'print $2')
echo "key: $key | value: $value"
done
I expect an output like:
key: VAR1 | value: VAL1
...
However, I'm getting that:
VAR1 VAL1 VAR2 VAL2 VAR3 VAL3
VAR1
key: VAR1 | value:
VAL1
key: VAL1 | value:
VAR2
key: VAR2 | value:
VAL2
key: VAL2 | value:
VAR3
key: VAR3 | value:
VAL3
key: VAL3 | value:
EDIT
$ echo "$KVS_VARIABLES" ->
VAR1 VAL1
VAR2 VAL2
VAR3 VAL3
shell-script
edited Jun 28 at 8:13
asked Jun 28 at 7:53
Jordi
1424
1424
closed as off-topic by Jeff Schaller, Kiwy, Zachary Brady, thrig, Rui F Ribeiro Jun 29 at 22:53
This question appears to be off-topic. The users who voted to close gave this specific reason:
- "This question has been posted on multiple sites. Cross-posting is strongly discouraged; see the help center and community FAQ for more information." â Jeff Schaller, Kiwy, Zachary Brady, thrig, Rui F Ribeiro
closed as off-topic by Jeff Schaller, Kiwy, Zachary Brady, thrig, Rui F Ribeiro Jun 29 at 22:53
This question appears to be off-topic. The users who voted to close gave this specific reason:
- "This question has been posted on multiple sites. Cross-posting is strongly discouraged; see the help center and community FAQ for more information." â Jeff Schaller, Kiwy, Zachary Brady, thrig, Rui F Ribeiro
if you use double quotes like this.. then are you getting the one key value in each row ? echo "$KVS_VARIABLES"
â Kamaraj
Jun 28 at 7:58
paste the output of echo "$KVS_VARIABLES" ---> (use double quotes)
â Kamaraj
Jun 28 at 7:59
stackoverflow.com/q/51077172/4957508
â Jeff Schaller
Jun 28 at 10:12
A simpler way to print to stderr from awk:print "some string" > "/dev/stderr"
â glenn jackman
Jun 28 at 11:43
You'll want to read mywiki.wooledge.org/BashFAQ/001: "How can I read a file (data stream, variable) line-by-line (and/or field-by-field)?" The first advice is "Don't try to use "for". Use a while loop and the read command. "
â glenn jackman
Jun 28 at 11:45
 |Â
show 1 more comment
if you use double quotes like this.. then are you getting the one key value in each row ? echo "$KVS_VARIABLES"
â Kamaraj
Jun 28 at 7:58
paste the output of echo "$KVS_VARIABLES" ---> (use double quotes)
â Kamaraj
Jun 28 at 7:59
stackoverflow.com/q/51077172/4957508
â Jeff Schaller
Jun 28 at 10:12
A simpler way to print to stderr from awk:print "some string" > "/dev/stderr"
â glenn jackman
Jun 28 at 11:43
You'll want to read mywiki.wooledge.org/BashFAQ/001: "How can I read a file (data stream, variable) line-by-line (and/or field-by-field)?" The first advice is "Don't try to use "for". Use a while loop and the read command. "
â glenn jackman
Jun 28 at 11:45
if you use double quotes like this.. then are you getting the one key value in each row ? echo "$KVS_VARIABLES"
â Kamaraj
Jun 28 at 7:58
if you use double quotes like this.. then are you getting the one key value in each row ? echo "$KVS_VARIABLES"
â Kamaraj
Jun 28 at 7:58
paste the output of echo "$KVS_VARIABLES" ---> (use double quotes)
â Kamaraj
Jun 28 at 7:59
paste the output of echo "$KVS_VARIABLES" ---> (use double quotes)
â Kamaraj
Jun 28 at 7:59
stackoverflow.com/q/51077172/4957508
â Jeff Schaller
Jun 28 at 10:12
stackoverflow.com/q/51077172/4957508
â Jeff Schaller
Jun 28 at 10:12
A simpler way to print to stderr from awk:
print "some string" > "/dev/stderr"â glenn jackman
Jun 28 at 11:43
A simpler way to print to stderr from awk:
print "some string" > "/dev/stderr"â glenn jackman
Jun 28 at 11:43
You'll want to read mywiki.wooledge.org/BashFAQ/001: "How can I read a file (data stream, variable) line-by-line (and/or field-by-field)?" The first advice is "Don't try to use "for". Use a while loop and the read command. "
â glenn jackman
Jun 28 at 11:45
You'll want to read mywiki.wooledge.org/BashFAQ/001: "How can I read a file (data stream, variable) line-by-line (and/or field-by-field)?" The first advice is "Don't try to use "for". Use a while loop and the read command. "
â glenn jackman
Jun 28 at 11:45
 |Â
show 1 more comment
3 Answers
3
active
oldest
votes
up vote
1
down vote
You need to specify IFS as newline, by default input file separator (IFS) includes a space and hence your for loop is behaving this way
KVS_VARIABLES=$(awk -F= '!($1 && $2 && NF==2) "cat 1>&2"; next print $1, $2 ' $ENV_FILE_LOCATION)
echo $KVS_VARIABLES
IFS=$(echo -en "nb")
for kv in $KVS_VARIABLES
do
echo $kv
key=$(echo $kv | awk 'print $1')
value=$(echo $kv | awk 'print $2')
echo "key: $key | value: $value"
done
add a comment |Â
up vote
1
down vote
Try:
#!/bin/bash
KVS_VARIABLES=$(echo -e "VAR1 VAL1nVAR2 VAL2nVAR3 VAL3n")
echo "KVS_VARIABLES=[$KVS_VARIABLES]"
while read -r kv; do
echo "kv = $kv"
key=$(echo $kv | awk 'print $1')
value=$(echo $kv | awk 'print $2')
echo "key: $key | value: $value"
done <<< "$KVS_VARIABLES"
You should get
KVS_VARIABLES=[VAR1 VAL1
VAR2 VAL2
VAR3 VAL3]
kv = VAR1 VAL1
key: VAR1 | value: VAL1
kv = VAR2 VAL2
key: VAR2 | value: VAL2
kv = VAR3 VAL3
key: VAR3 | value: VAL3
add a comment |Â
up vote
0
down vote
As Arushix points out, one of the issues with the code is that read splits the input on the values in the shell variable IFS (space, tab and newline by default).
However, I can't help but notice that your are parsing the variables in the original file several times; first by the first awk script, and then again with the read, and finally a third time with echo+awk. Each of these steps may throw its own set of errors.
If you just want to validate the variable assignments and print out the key/value pairs:
if ! awk -F '=' 'NF != 2 exit 1 printf("key: %s ' "$conffile"; then
echo 'Failed' >&2
exit 1
fi
Given the input file
VAR1=VAL1
VAR2=VAL2
VAR3=VAL3
VAR4=VAL4
This will print
key: VAR1 | value: VAL1
key: VAR2 | value: VAL2
key: VAR3 | value: VAL3
key: VAR4 | value: VAL4
With an extra line reading just BOO at the end of the input file, the output would instead be
key: VAR1 | value: VAL1
key: VAR2 | value: VAL2
key: VAR3 | value: VAL3
key: VAR4 | value: VAL4
Failed
In addition to NF == 2, you may want to include a check for valid variable names etc.:
if ! awk -F '=' 'NF != 2 || $1 !~ /^[A-Za-z][A-Za-z0-9]+$/ exit 1 printf("key: %s ' "$conffile"; then
echo 'Failed' >&2
exit 1
fi
add a comment |Â
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
You need to specify IFS as newline, by default input file separator (IFS) includes a space and hence your for loop is behaving this way
KVS_VARIABLES=$(awk -F= '!($1 && $2 && NF==2) "cat 1>&2"; next print $1, $2 ' $ENV_FILE_LOCATION)
echo $KVS_VARIABLES
IFS=$(echo -en "nb")
for kv in $KVS_VARIABLES
do
echo $kv
key=$(echo $kv | awk 'print $1')
value=$(echo $kv | awk 'print $2')
echo "key: $key | value: $value"
done
add a comment |Â
up vote
1
down vote
You need to specify IFS as newline, by default input file separator (IFS) includes a space and hence your for loop is behaving this way
KVS_VARIABLES=$(awk -F= '!($1 && $2 && NF==2) "cat 1>&2"; next print $1, $2 ' $ENV_FILE_LOCATION)
echo $KVS_VARIABLES
IFS=$(echo -en "nb")
for kv in $KVS_VARIABLES
do
echo $kv
key=$(echo $kv | awk 'print $1')
value=$(echo $kv | awk 'print $2')
echo "key: $key | value: $value"
done
add a comment |Â
up vote
1
down vote
up vote
1
down vote
You need to specify IFS as newline, by default input file separator (IFS) includes a space and hence your for loop is behaving this way
KVS_VARIABLES=$(awk -F= '!($1 && $2 && NF==2) "cat 1>&2"; next print $1, $2 ' $ENV_FILE_LOCATION)
echo $KVS_VARIABLES
IFS=$(echo -en "nb")
for kv in $KVS_VARIABLES
do
echo $kv
key=$(echo $kv | awk 'print $1')
value=$(echo $kv | awk 'print $2')
echo "key: $key | value: $value"
done
You need to specify IFS as newline, by default input file separator (IFS) includes a space and hence your for loop is behaving this way
KVS_VARIABLES=$(awk -F= '!($1 && $2 && NF==2) "cat 1>&2"; next print $1, $2 ' $ENV_FILE_LOCATION)
echo $KVS_VARIABLES
IFS=$(echo -en "nb")
for kv in $KVS_VARIABLES
do
echo $kv
key=$(echo $kv | awk 'print $1')
value=$(echo $kv | awk 'print $2')
echo "key: $key | value: $value"
done
edited Jun 28 at 8:39
Kusalananda
101k13199312
101k13199312
answered Jun 28 at 8:37
Arushix
9968
9968
add a comment |Â
add a comment |Â
up vote
1
down vote
Try:
#!/bin/bash
KVS_VARIABLES=$(echo -e "VAR1 VAL1nVAR2 VAL2nVAR3 VAL3n")
echo "KVS_VARIABLES=[$KVS_VARIABLES]"
while read -r kv; do
echo "kv = $kv"
key=$(echo $kv | awk 'print $1')
value=$(echo $kv | awk 'print $2')
echo "key: $key | value: $value"
done <<< "$KVS_VARIABLES"
You should get
KVS_VARIABLES=[VAR1 VAL1
VAR2 VAL2
VAR3 VAL3]
kv = VAR1 VAL1
key: VAR1 | value: VAL1
kv = VAR2 VAL2
key: VAR2 | value: VAL2
kv = VAR3 VAL3
key: VAR3 | value: VAL3
add a comment |Â
up vote
1
down vote
Try:
#!/bin/bash
KVS_VARIABLES=$(echo -e "VAR1 VAL1nVAR2 VAL2nVAR3 VAL3n")
echo "KVS_VARIABLES=[$KVS_VARIABLES]"
while read -r kv; do
echo "kv = $kv"
key=$(echo $kv | awk 'print $1')
value=$(echo $kv | awk 'print $2')
echo "key: $key | value: $value"
done <<< "$KVS_VARIABLES"
You should get
KVS_VARIABLES=[VAR1 VAL1
VAR2 VAL2
VAR3 VAL3]
kv = VAR1 VAL1
key: VAR1 | value: VAL1
kv = VAR2 VAL2
key: VAR2 | value: VAL2
kv = VAR3 VAL3
key: VAR3 | value: VAL3
add a comment |Â
up vote
1
down vote
up vote
1
down vote
Try:
#!/bin/bash
KVS_VARIABLES=$(echo -e "VAR1 VAL1nVAR2 VAL2nVAR3 VAL3n")
echo "KVS_VARIABLES=[$KVS_VARIABLES]"
while read -r kv; do
echo "kv = $kv"
key=$(echo $kv | awk 'print $1')
value=$(echo $kv | awk 'print $2')
echo "key: $key | value: $value"
done <<< "$KVS_VARIABLES"
You should get
KVS_VARIABLES=[VAR1 VAL1
VAR2 VAL2
VAR3 VAL3]
kv = VAR1 VAL1
key: VAR1 | value: VAL1
kv = VAR2 VAL2
key: VAR2 | value: VAL2
kv = VAR3 VAL3
key: VAR3 | value: VAL3
Try:
#!/bin/bash
KVS_VARIABLES=$(echo -e "VAR1 VAL1nVAR2 VAL2nVAR3 VAL3n")
echo "KVS_VARIABLES=[$KVS_VARIABLES]"
while read -r kv; do
echo "kv = $kv"
key=$(echo $kv | awk 'print $1')
value=$(echo $kv | awk 'print $2')
echo "key: $key | value: $value"
done <<< "$KVS_VARIABLES"
You should get
KVS_VARIABLES=[VAR1 VAL1
VAR2 VAL2
VAR3 VAL3]
kv = VAR1 VAL1
key: VAR1 | value: VAL1
kv = VAR2 VAL2
key: VAR2 | value: VAL2
kv = VAR3 VAL3
key: VAR3 | value: VAL3
answered Jun 28 at 8:40
Alessandro Carini
615
615
add a comment |Â
add a comment |Â
up vote
0
down vote
As Arushix points out, one of the issues with the code is that read splits the input on the values in the shell variable IFS (space, tab and newline by default).
However, I can't help but notice that your are parsing the variables in the original file several times; first by the first awk script, and then again with the read, and finally a third time with echo+awk. Each of these steps may throw its own set of errors.
If you just want to validate the variable assignments and print out the key/value pairs:
if ! awk -F '=' 'NF != 2 exit 1 printf("key: %s ' "$conffile"; then
echo 'Failed' >&2
exit 1
fi
Given the input file
VAR1=VAL1
VAR2=VAL2
VAR3=VAL3
VAR4=VAL4
This will print
key: VAR1 | value: VAL1
key: VAR2 | value: VAL2
key: VAR3 | value: VAL3
key: VAR4 | value: VAL4
With an extra line reading just BOO at the end of the input file, the output would instead be
key: VAR1 | value: VAL1
key: VAR2 | value: VAL2
key: VAR3 | value: VAL3
key: VAR4 | value: VAL4
Failed
In addition to NF == 2, you may want to include a check for valid variable names etc.:
if ! awk -F '=' 'NF != 2 || $1 !~ /^[A-Za-z][A-Za-z0-9]+$/ exit 1 printf("key: %s ' "$conffile"; then
echo 'Failed' >&2
exit 1
fi
add a comment |Â
up vote
0
down vote
As Arushix points out, one of the issues with the code is that read splits the input on the values in the shell variable IFS (space, tab and newline by default).
However, I can't help but notice that your are parsing the variables in the original file several times; first by the first awk script, and then again with the read, and finally a third time with echo+awk. Each of these steps may throw its own set of errors.
If you just want to validate the variable assignments and print out the key/value pairs:
if ! awk -F '=' 'NF != 2 exit 1 printf("key: %s ' "$conffile"; then
echo 'Failed' >&2
exit 1
fi
Given the input file
VAR1=VAL1
VAR2=VAL2
VAR3=VAL3
VAR4=VAL4
This will print
key: VAR1 | value: VAL1
key: VAR2 | value: VAL2
key: VAR3 | value: VAL3
key: VAR4 | value: VAL4
With an extra line reading just BOO at the end of the input file, the output would instead be
key: VAR1 | value: VAL1
key: VAR2 | value: VAL2
key: VAR3 | value: VAL3
key: VAR4 | value: VAL4
Failed
In addition to NF == 2, you may want to include a check for valid variable names etc.:
if ! awk -F '=' 'NF != 2 || $1 !~ /^[A-Za-z][A-Za-z0-9]+$/ exit 1 printf("key: %s ' "$conffile"; then
echo 'Failed' >&2
exit 1
fi
add a comment |Â
up vote
0
down vote
up vote
0
down vote
As Arushix points out, one of the issues with the code is that read splits the input on the values in the shell variable IFS (space, tab and newline by default).
However, I can't help but notice that your are parsing the variables in the original file several times; first by the first awk script, and then again with the read, and finally a third time with echo+awk. Each of these steps may throw its own set of errors.
If you just want to validate the variable assignments and print out the key/value pairs:
if ! awk -F '=' 'NF != 2 exit 1 printf("key: %s ' "$conffile"; then
echo 'Failed' >&2
exit 1
fi
Given the input file
VAR1=VAL1
VAR2=VAL2
VAR3=VAL3
VAR4=VAL4
This will print
key: VAR1 | value: VAL1
key: VAR2 | value: VAL2
key: VAR3 | value: VAL3
key: VAR4 | value: VAL4
With an extra line reading just BOO at the end of the input file, the output would instead be
key: VAR1 | value: VAL1
key: VAR2 | value: VAL2
key: VAR3 | value: VAL3
key: VAR4 | value: VAL4
Failed
In addition to NF == 2, you may want to include a check for valid variable names etc.:
if ! awk -F '=' 'NF != 2 || $1 !~ /^[A-Za-z][A-Za-z0-9]+$/ exit 1 printf("key: %s ' "$conffile"; then
echo 'Failed' >&2
exit 1
fi
As Arushix points out, one of the issues with the code is that read splits the input on the values in the shell variable IFS (space, tab and newline by default).
However, I can't help but notice that your are parsing the variables in the original file several times; first by the first awk script, and then again with the read, and finally a third time with echo+awk. Each of these steps may throw its own set of errors.
If you just want to validate the variable assignments and print out the key/value pairs:
if ! awk -F '=' 'NF != 2 exit 1 printf("key: %s ' "$conffile"; then
echo 'Failed' >&2
exit 1
fi
Given the input file
VAR1=VAL1
VAR2=VAL2
VAR3=VAL3
VAR4=VAL4
This will print
key: VAR1 | value: VAL1
key: VAR2 | value: VAL2
key: VAR3 | value: VAL3
key: VAR4 | value: VAL4
With an extra line reading just BOO at the end of the input file, the output would instead be
key: VAR1 | value: VAL1
key: VAR2 | value: VAL2
key: VAR3 | value: VAL3
key: VAR4 | value: VAL4
Failed
In addition to NF == 2, you may want to include a check for valid variable names etc.:
if ! awk -F '=' 'NF != 2 || $1 !~ /^[A-Za-z][A-Za-z0-9]+$/ exit 1 printf("key: %s ' "$conffile"; then
echo 'Failed' >&2
exit 1
fi
answered Jun 28 at 8:51
Kusalananda
101k13199312
101k13199312
add a comment |Â
add a comment |Â
if you use double quotes like this.. then are you getting the one key value in each row ? echo "$KVS_VARIABLES"
â Kamaraj
Jun 28 at 7:58
paste the output of echo "$KVS_VARIABLES" ---> (use double quotes)
â Kamaraj
Jun 28 at 7:59
stackoverflow.com/q/51077172/4957508
â Jeff Schaller
Jun 28 at 10:12
A simpler way to print to stderr from awk:
print "some string" > "/dev/stderr"â glenn jackman
Jun 28 at 11:43
You'll want to read mywiki.wooledge.org/BashFAQ/001: "How can I read a file (data stream, variable) line-by-line (and/or field-by-field)?" The first advice is "Don't try to use "for". Use a while loop and the read command. "
â glenn jackman
Jun 28 at 11:45