How to cut a string based on delimiter which is having space
Clash Royale CLAN TAG#URR8PPP
up vote
1
down vote
favorite
variable_list="
any:any:-a -b -c any
one:one:-c -b -f -m mul
mul:one:-c -b -f -m mul
"
for f in `echo $variable_list`
do
c1=`echo $f | cut -d':' -f1`;
c2=`echo $f | cut -d':' -f2`;
c3=`echo $f | cut -d':' -f3-`;
echo "c1==>$c1 and c2==>$c2 and c3==>$c3";
#exit 0; ###I made mistake here
done;
Expected Output:
c1==>any and c2==>any and c3==>-a -b -c any
c1==>one and c2==>one and c3==>-c -b -f -m mul
c1==>mul and c2==>one and c3==>-c -b -f -m mul
Edit 1:
I realized that I was stupid while using the script and at first iteration I used exit 0
to test it only first line since I have lots of this in real. It was working as it has to be.
Can I achieve the mentioned output by maintaining the variable_list
with out modifying the format/way of input?
(I am using bash)
cut
add a comment |Â
up vote
1
down vote
favorite
variable_list="
any:any:-a -b -c any
one:one:-c -b -f -m mul
mul:one:-c -b -f -m mul
"
for f in `echo $variable_list`
do
c1=`echo $f | cut -d':' -f1`;
c2=`echo $f | cut -d':' -f2`;
c3=`echo $f | cut -d':' -f3-`;
echo "c1==>$c1 and c2==>$c2 and c3==>$c3";
#exit 0; ###I made mistake here
done;
Expected Output:
c1==>any and c2==>any and c3==>-a -b -c any
c1==>one and c2==>one and c3==>-c -b -f -m mul
c1==>mul and c2==>one and c3==>-c -b -f -m mul
Edit 1:
I realized that I was stupid while using the script and at first iteration I used exit 0
to test it only first line since I have lots of this in real. It was working as it has to be.
Can I achieve the mentioned output by maintaining the variable_list
with out modifying the format/way of input?
(I am using bash)
cut
3
cannot reproduce here; is that the exact and complete command you're running?
â Jeff Schaller
Jul 12 at 14:13
1
cut -d: -f3 < input
works; as doescut -d: -f3- < input
â Jeff Schaller
Jul 12 at 14:15
I am using inside a variable, I will add more information in the question.
â Spike
Jul 12 at 14:15
2
How are you using the variable and how do you assign to the variable?
â Kusalananda
Jul 12 at 14:20
add a comment |Â
up vote
1
down vote
favorite
up vote
1
down vote
favorite
variable_list="
any:any:-a -b -c any
one:one:-c -b -f -m mul
mul:one:-c -b -f -m mul
"
for f in `echo $variable_list`
do
c1=`echo $f | cut -d':' -f1`;
c2=`echo $f | cut -d':' -f2`;
c3=`echo $f | cut -d':' -f3-`;
echo "c1==>$c1 and c2==>$c2 and c3==>$c3";
#exit 0; ###I made mistake here
done;
Expected Output:
c1==>any and c2==>any and c3==>-a -b -c any
c1==>one and c2==>one and c3==>-c -b -f -m mul
c1==>mul and c2==>one and c3==>-c -b -f -m mul
Edit 1:
I realized that I was stupid while using the script and at first iteration I used exit 0
to test it only first line since I have lots of this in real. It was working as it has to be.
Can I achieve the mentioned output by maintaining the variable_list
with out modifying the format/way of input?
(I am using bash)
cut
variable_list="
any:any:-a -b -c any
one:one:-c -b -f -m mul
mul:one:-c -b -f -m mul
"
for f in `echo $variable_list`
do
c1=`echo $f | cut -d':' -f1`;
c2=`echo $f | cut -d':' -f2`;
c3=`echo $f | cut -d':' -f3-`;
echo "c1==>$c1 and c2==>$c2 and c3==>$c3";
#exit 0; ###I made mistake here
done;
Expected Output:
c1==>any and c2==>any and c3==>-a -b -c any
c1==>one and c2==>one and c3==>-c -b -f -m mul
c1==>mul and c2==>one and c3==>-c -b -f -m mul
Edit 1:
I realized that I was stupid while using the script and at first iteration I used exit 0
to test it only first line since I have lots of this in real. It was working as it has to be.
Can I achieve the mentioned output by maintaining the variable_list
with out modifying the format/way of input?
(I am using bash)
cut
edited Jul 12 at 14:40
asked Jul 12 at 14:11
Spike
1991213
1991213
3
cannot reproduce here; is that the exact and complete command you're running?
â Jeff Schaller
Jul 12 at 14:13
1
cut -d: -f3 < input
works; as doescut -d: -f3- < input
â Jeff Schaller
Jul 12 at 14:15
I am using inside a variable, I will add more information in the question.
â Spike
Jul 12 at 14:15
2
How are you using the variable and how do you assign to the variable?
â Kusalananda
Jul 12 at 14:20
add a comment |Â
3
cannot reproduce here; is that the exact and complete command you're running?
â Jeff Schaller
Jul 12 at 14:13
1
cut -d: -f3 < input
works; as doescut -d: -f3- < input
â Jeff Schaller
Jul 12 at 14:15
I am using inside a variable, I will add more information in the question.
â Spike
Jul 12 at 14:15
2
How are you using the variable and how do you assign to the variable?
â Kusalananda
Jul 12 at 14:20
3
3
cannot reproduce here; is that the exact and complete command you're running?
â Jeff Schaller
Jul 12 at 14:13
cannot reproduce here; is that the exact and complete command you're running?
â Jeff Schaller
Jul 12 at 14:13
1
1
cut -d: -f3 < input
works; as does cut -d: -f3- < input
â Jeff Schaller
Jul 12 at 14:15
cut -d: -f3 < input
works; as does cut -d: -f3- < input
â Jeff Schaller
Jul 12 at 14:15
I am using inside a variable, I will add more information in the question.
â Spike
Jul 12 at 14:15
I am using inside a variable, I will add more information in the question.
â Spike
Jul 12 at 14:15
2
2
How are you using the variable and how do you assign to the variable?
â Kusalananda
Jul 12 at 14:20
How are you using the variable and how do you assign to the variable?
â Kusalananda
Jul 12 at 14:20
add a comment |Â
2 Answers
2
active
oldest
votes
up vote
5
down vote
accepted
Your issue are with the spaces in the data. The shell will split the string into words on all spaces and the for
loop will iterate over those words.
(For a solution that does not replace variable_list
with an array, see the very end of this answer.)
Instead, use a proper array:
variable_list=(
"any:any:-a -b -c any"
"one:one:-c -b -f -m mul"
"mul:one:-c -b -f -m mul"
)
for var in "$variable_list[@]"; do
c1=$( cut -d':' -f1 <<<"$var" )
c2=$( cut -d':' -f2 <<<"$var" )
c3=$( cut -d':' -f3- <<<"$var" )
printf 'c1==>%s and c2==>%s and c3==>%sn' "$c1" "$c2" "$c3"
done
Using an array ensures that you can access each individual set of variables as its own array entry without relying on them being delimited by newlines or some other character.
The code is also using "here-strings" in bash
to send the string to cut
(rather than echo
and a pipe).
Or, much more efficiently,
variable_list=(
"any:any:-a -b -c any"
"one:one:-c -b -f -m mul"
"mul:one:-c -b -f -m mul"
)
for var in "$variable_list[@]"; do
IFS=':' read -r c1 c2 c3 <<<"$var"
printf 'c1==>%s and c2==>%s and c3==>%sn' "$c1" "$c2" "$c3"
done
Setting IFS
to a colon for read
will make read
split the input on colons (rather than on spaces, tabs and newlines).
Note that all the quotation above is significant. Without the double quotes, the shell would perform word splitting and filename globbing on the values of variable_list
, var
and the three c
variables.
Related:
- When is double-quoting necessary?
- Why is printf better than echo?
- Have backticks (i.e. `cmd`) in *sh shells been deprecated?
If all you're after is that specific output, then you may cheat a bit:
variable_list=(
"any:any:-a -b -c any"
"one:one:-c -b -f -m mul"
"mul:one:-c -b -f -m mul"
)
( IFS=':'; set -f; printf 'c1==>%s and c2==>%s and c3==>%sn' $variable_list[@] )
This runs the printf
in a subshell so that setting IFS
and the -f
(noglob
) shell option does not affect the rest of the script. Setting IFS
to a colon here will make the shell expand the unquoted variable_list
array into three sets of three arguments for printf
. printf
will print the first three according to its format string and then reuse that format for the next set of three arguments, until all arguments have been processed.
The set -f
prevents the unquoted expansion of variable_list
from triggering filename globbing, should there be any filename globbing characters in there.
Using a newline-delimited string:
variable_list="
any:any:-a -b -c any
one:one:-c -b -f -m mul
mul:one:-c -b -f -m mul"
while IFS= read -r var; do
IFS=':' read -r c1 c2 c3 <<<"$var"
printf 'c1==>%s and c2==>%s and c3==>%sn' "$c1" "$c2" "$c3"
done <<<"$variable_list"
This reads the data from the string as if it came from a file.
Related:
- Understanding "IFS= read -r line"
add a comment |Â
up vote
0
down vote
You can use awk to get your output :
echo "$variable_list" | awk -F: '
sub("^ ","")
for(i=1;i<=NF;i++)
sub(/^/,"c" i "==>",$i)
1' OFS=" and "
add a comment |Â
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
5
down vote
accepted
Your issue are with the spaces in the data. The shell will split the string into words on all spaces and the for
loop will iterate over those words.
(For a solution that does not replace variable_list
with an array, see the very end of this answer.)
Instead, use a proper array:
variable_list=(
"any:any:-a -b -c any"
"one:one:-c -b -f -m mul"
"mul:one:-c -b -f -m mul"
)
for var in "$variable_list[@]"; do
c1=$( cut -d':' -f1 <<<"$var" )
c2=$( cut -d':' -f2 <<<"$var" )
c3=$( cut -d':' -f3- <<<"$var" )
printf 'c1==>%s and c2==>%s and c3==>%sn' "$c1" "$c2" "$c3"
done
Using an array ensures that you can access each individual set of variables as its own array entry without relying on them being delimited by newlines or some other character.
The code is also using "here-strings" in bash
to send the string to cut
(rather than echo
and a pipe).
Or, much more efficiently,
variable_list=(
"any:any:-a -b -c any"
"one:one:-c -b -f -m mul"
"mul:one:-c -b -f -m mul"
)
for var in "$variable_list[@]"; do
IFS=':' read -r c1 c2 c3 <<<"$var"
printf 'c1==>%s and c2==>%s and c3==>%sn' "$c1" "$c2" "$c3"
done
Setting IFS
to a colon for read
will make read
split the input on colons (rather than on spaces, tabs and newlines).
Note that all the quotation above is significant. Without the double quotes, the shell would perform word splitting and filename globbing on the values of variable_list
, var
and the three c
variables.
Related:
- When is double-quoting necessary?
- Why is printf better than echo?
- Have backticks (i.e. `cmd`) in *sh shells been deprecated?
If all you're after is that specific output, then you may cheat a bit:
variable_list=(
"any:any:-a -b -c any"
"one:one:-c -b -f -m mul"
"mul:one:-c -b -f -m mul"
)
( IFS=':'; set -f; printf 'c1==>%s and c2==>%s and c3==>%sn' $variable_list[@] )
This runs the printf
in a subshell so that setting IFS
and the -f
(noglob
) shell option does not affect the rest of the script. Setting IFS
to a colon here will make the shell expand the unquoted variable_list
array into three sets of three arguments for printf
. printf
will print the first three according to its format string and then reuse that format for the next set of three arguments, until all arguments have been processed.
The set -f
prevents the unquoted expansion of variable_list
from triggering filename globbing, should there be any filename globbing characters in there.
Using a newline-delimited string:
variable_list="
any:any:-a -b -c any
one:one:-c -b -f -m mul
mul:one:-c -b -f -m mul"
while IFS= read -r var; do
IFS=':' read -r c1 c2 c3 <<<"$var"
printf 'c1==>%s and c2==>%s and c3==>%sn' "$c1" "$c2" "$c3"
done <<<"$variable_list"
This reads the data from the string as if it came from a file.
Related:
- Understanding "IFS= read -r line"
add a comment |Â
up vote
5
down vote
accepted
Your issue are with the spaces in the data. The shell will split the string into words on all spaces and the for
loop will iterate over those words.
(For a solution that does not replace variable_list
with an array, see the very end of this answer.)
Instead, use a proper array:
variable_list=(
"any:any:-a -b -c any"
"one:one:-c -b -f -m mul"
"mul:one:-c -b -f -m mul"
)
for var in "$variable_list[@]"; do
c1=$( cut -d':' -f1 <<<"$var" )
c2=$( cut -d':' -f2 <<<"$var" )
c3=$( cut -d':' -f3- <<<"$var" )
printf 'c1==>%s and c2==>%s and c3==>%sn' "$c1" "$c2" "$c3"
done
Using an array ensures that you can access each individual set of variables as its own array entry without relying on them being delimited by newlines or some other character.
The code is also using "here-strings" in bash
to send the string to cut
(rather than echo
and a pipe).
Or, much more efficiently,
variable_list=(
"any:any:-a -b -c any"
"one:one:-c -b -f -m mul"
"mul:one:-c -b -f -m mul"
)
for var in "$variable_list[@]"; do
IFS=':' read -r c1 c2 c3 <<<"$var"
printf 'c1==>%s and c2==>%s and c3==>%sn' "$c1" "$c2" "$c3"
done
Setting IFS
to a colon for read
will make read
split the input on colons (rather than on spaces, tabs and newlines).
Note that all the quotation above is significant. Without the double quotes, the shell would perform word splitting and filename globbing on the values of variable_list
, var
and the three c
variables.
Related:
- When is double-quoting necessary?
- Why is printf better than echo?
- Have backticks (i.e. `cmd`) in *sh shells been deprecated?
If all you're after is that specific output, then you may cheat a bit:
variable_list=(
"any:any:-a -b -c any"
"one:one:-c -b -f -m mul"
"mul:one:-c -b -f -m mul"
)
( IFS=':'; set -f; printf 'c1==>%s and c2==>%s and c3==>%sn' $variable_list[@] )
This runs the printf
in a subshell so that setting IFS
and the -f
(noglob
) shell option does not affect the rest of the script. Setting IFS
to a colon here will make the shell expand the unquoted variable_list
array into three sets of three arguments for printf
. printf
will print the first three according to its format string and then reuse that format for the next set of three arguments, until all arguments have been processed.
The set -f
prevents the unquoted expansion of variable_list
from triggering filename globbing, should there be any filename globbing characters in there.
Using a newline-delimited string:
variable_list="
any:any:-a -b -c any
one:one:-c -b -f -m mul
mul:one:-c -b -f -m mul"
while IFS= read -r var; do
IFS=':' read -r c1 c2 c3 <<<"$var"
printf 'c1==>%s and c2==>%s and c3==>%sn' "$c1" "$c2" "$c3"
done <<<"$variable_list"
This reads the data from the string as if it came from a file.
Related:
- Understanding "IFS= read -r line"
add a comment |Â
up vote
5
down vote
accepted
up vote
5
down vote
accepted
Your issue are with the spaces in the data. The shell will split the string into words on all spaces and the for
loop will iterate over those words.
(For a solution that does not replace variable_list
with an array, see the very end of this answer.)
Instead, use a proper array:
variable_list=(
"any:any:-a -b -c any"
"one:one:-c -b -f -m mul"
"mul:one:-c -b -f -m mul"
)
for var in "$variable_list[@]"; do
c1=$( cut -d':' -f1 <<<"$var" )
c2=$( cut -d':' -f2 <<<"$var" )
c3=$( cut -d':' -f3- <<<"$var" )
printf 'c1==>%s and c2==>%s and c3==>%sn' "$c1" "$c2" "$c3"
done
Using an array ensures that you can access each individual set of variables as its own array entry without relying on them being delimited by newlines or some other character.
The code is also using "here-strings" in bash
to send the string to cut
(rather than echo
and a pipe).
Or, much more efficiently,
variable_list=(
"any:any:-a -b -c any"
"one:one:-c -b -f -m mul"
"mul:one:-c -b -f -m mul"
)
for var in "$variable_list[@]"; do
IFS=':' read -r c1 c2 c3 <<<"$var"
printf 'c1==>%s and c2==>%s and c3==>%sn' "$c1" "$c2" "$c3"
done
Setting IFS
to a colon for read
will make read
split the input on colons (rather than on spaces, tabs and newlines).
Note that all the quotation above is significant. Without the double quotes, the shell would perform word splitting and filename globbing on the values of variable_list
, var
and the three c
variables.
Related:
- When is double-quoting necessary?
- Why is printf better than echo?
- Have backticks (i.e. `cmd`) in *sh shells been deprecated?
If all you're after is that specific output, then you may cheat a bit:
variable_list=(
"any:any:-a -b -c any"
"one:one:-c -b -f -m mul"
"mul:one:-c -b -f -m mul"
)
( IFS=':'; set -f; printf 'c1==>%s and c2==>%s and c3==>%sn' $variable_list[@] )
This runs the printf
in a subshell so that setting IFS
and the -f
(noglob
) shell option does not affect the rest of the script. Setting IFS
to a colon here will make the shell expand the unquoted variable_list
array into three sets of three arguments for printf
. printf
will print the first three according to its format string and then reuse that format for the next set of three arguments, until all arguments have been processed.
The set -f
prevents the unquoted expansion of variable_list
from triggering filename globbing, should there be any filename globbing characters in there.
Using a newline-delimited string:
variable_list="
any:any:-a -b -c any
one:one:-c -b -f -m mul
mul:one:-c -b -f -m mul"
while IFS= read -r var; do
IFS=':' read -r c1 c2 c3 <<<"$var"
printf 'c1==>%s and c2==>%s and c3==>%sn' "$c1" "$c2" "$c3"
done <<<"$variable_list"
This reads the data from the string as if it came from a file.
Related:
- Understanding "IFS= read -r line"
Your issue are with the spaces in the data. The shell will split the string into words on all spaces and the for
loop will iterate over those words.
(For a solution that does not replace variable_list
with an array, see the very end of this answer.)
Instead, use a proper array:
variable_list=(
"any:any:-a -b -c any"
"one:one:-c -b -f -m mul"
"mul:one:-c -b -f -m mul"
)
for var in "$variable_list[@]"; do
c1=$( cut -d':' -f1 <<<"$var" )
c2=$( cut -d':' -f2 <<<"$var" )
c3=$( cut -d':' -f3- <<<"$var" )
printf 'c1==>%s and c2==>%s and c3==>%sn' "$c1" "$c2" "$c3"
done
Using an array ensures that you can access each individual set of variables as its own array entry without relying on them being delimited by newlines or some other character.
The code is also using "here-strings" in bash
to send the string to cut
(rather than echo
and a pipe).
Or, much more efficiently,
variable_list=(
"any:any:-a -b -c any"
"one:one:-c -b -f -m mul"
"mul:one:-c -b -f -m mul"
)
for var in "$variable_list[@]"; do
IFS=':' read -r c1 c2 c3 <<<"$var"
printf 'c1==>%s and c2==>%s and c3==>%sn' "$c1" "$c2" "$c3"
done
Setting IFS
to a colon for read
will make read
split the input on colons (rather than on spaces, tabs and newlines).
Note that all the quotation above is significant. Without the double quotes, the shell would perform word splitting and filename globbing on the values of variable_list
, var
and the three c
variables.
Related:
- When is double-quoting necessary?
- Why is printf better than echo?
- Have backticks (i.e. `cmd`) in *sh shells been deprecated?
If all you're after is that specific output, then you may cheat a bit:
variable_list=(
"any:any:-a -b -c any"
"one:one:-c -b -f -m mul"
"mul:one:-c -b -f -m mul"
)
( IFS=':'; set -f; printf 'c1==>%s and c2==>%s and c3==>%sn' $variable_list[@] )
This runs the printf
in a subshell so that setting IFS
and the -f
(noglob
) shell option does not affect the rest of the script. Setting IFS
to a colon here will make the shell expand the unquoted variable_list
array into three sets of three arguments for printf
. printf
will print the first three according to its format string and then reuse that format for the next set of three arguments, until all arguments have been processed.
The set -f
prevents the unquoted expansion of variable_list
from triggering filename globbing, should there be any filename globbing characters in there.
Using a newline-delimited string:
variable_list="
any:any:-a -b -c any
one:one:-c -b -f -m mul
mul:one:-c -b -f -m mul"
while IFS= read -r var; do
IFS=':' read -r c1 c2 c3 <<<"$var"
printf 'c1==>%s and c2==>%s and c3==>%sn' "$c1" "$c2" "$c3"
done <<<"$variable_list"
This reads the data from the string as if it came from a file.
Related:
- Understanding "IFS= read -r line"
edited Jul 12 at 15:24
answered Jul 12 at 14:49
Kusalananda
101k13199312
101k13199312
add a comment |Â
add a comment |Â
up vote
0
down vote
You can use awk to get your output :
echo "$variable_list" | awk -F: '
sub("^ ","")
for(i=1;i<=NF;i++)
sub(/^/,"c" i "==>",$i)
1' OFS=" and "
add a comment |Â
up vote
0
down vote
You can use awk to get your output :
echo "$variable_list" | awk -F: '
sub("^ ","")
for(i=1;i<=NF;i++)
sub(/^/,"c" i "==>",$i)
1' OFS=" and "
add a comment |Â
up vote
0
down vote
up vote
0
down vote
You can use awk to get your output :
echo "$variable_list" | awk -F: '
sub("^ ","")
for(i=1;i<=NF;i++)
sub(/^/,"c" i "==>",$i)
1' OFS=" and "
You can use awk to get your output :
echo "$variable_list" | awk -F: '
sub("^ ","")
for(i=1;i<=NF;i++)
sub(/^/,"c" i "==>",$i)
1' OFS=" and "
answered Jul 12 at 18:29
ctac_
986116
986116
add a comment |Â
add a comment |Â
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
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f454912%2fhow-to-cut-a-string-based-on-delimiter-which-is-having-space%23new-answer', 'question_page');
);
Post as a guest
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
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
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
3
cannot reproduce here; is that the exact and complete command you're running?
â Jeff Schaller
Jul 12 at 14:13
1
cut -d: -f3 < input
works; as doescut -d: -f3- < input
â Jeff Schaller
Jul 12 at 14:15
I am using inside a variable, I will add more information in the question.
â Spike
Jul 12 at 14:15
2
How are you using the variable and how do you assign to the variable?
â Kusalananda
Jul 12 at 14:20