Read from file then use for to split fields but honor quotes
Clash Royale CLAN TAG#URR8PPP
This what I am trying to get in a bash shell script:
for a in "1" "2 3" "4 5 6"
do
echo "a: $a"
done
a: 1
a: 2 3
a: 4 5 6
But the quotes are treated differently when you use a variable:
echo ""1" "2 3" "4 5 6"" > a.txt
cat a.txt
"1" "2 3" "4 5 6"
read aline < a.txt
If you double-quote the variable, you get this:
for b in "$aline"
do
echo "b: $b"
done
b: "1" "2 3" "4 5 6"
And without quotes you get this:
for b in $aline
do
echo "b: $b"
done
b: "1"
b: "2
b: 3"
b: "4
b: 5
b: 6"
Is there a way to get the for to process the contents of the variable as in the first example?
bash for
add a comment |
This what I am trying to get in a bash shell script:
for a in "1" "2 3" "4 5 6"
do
echo "a: $a"
done
a: 1
a: 2 3
a: 4 5 6
But the quotes are treated differently when you use a variable:
echo ""1" "2 3" "4 5 6"" > a.txt
cat a.txt
"1" "2 3" "4 5 6"
read aline < a.txt
If you double-quote the variable, you get this:
for b in "$aline"
do
echo "b: $b"
done
b: "1" "2 3" "4 5 6"
And without quotes you get this:
for b in $aline
do
echo "b: $b"
done
b: "1"
b: "2
b: 3"
b: "4
b: 5
b: 6"
Is there a way to get the for to process the contents of the variable as in the first example?
bash for
Is there another issue that makes you ask this question? Do you have another problem that requires you to disable the shell's standard quote removal, which happens during the evaluation of a command?
– Kusalananda
Feb 21 at 6:43
@Kusalananda yeah, the OP said something to the effect that they simplified the example too much and here were the real thing, but it was cut short at the ":", and the message was immediately deleted. Let's hope that nothing bad happened to him <;-
– mosvy
Feb 21 at 7:19
This is my first time posting a question on this forum, so working out my bugs around posting/commenting. The first answer I got from mosvy gave me enough to work out a solution. The "set -- " seemed to be losing fields. It doesn't like having '#Mi' (no quotes) as one of the fields but once I realized that, I just ran it through sed and now I'm getting what I want. Thanks for the help.
– Linus Hicks
Feb 21 at 7:46
@LinusHicks If you're happy with one or several of the answers, upvote them. If one is solving your issue, accepting it would be the best way of saying "Thank You!" Accepting an answer also indicates to future readers that the answer actually solved the problem.
– Kusalananda
Feb 21 at 8:10
add a comment |
This what I am trying to get in a bash shell script:
for a in "1" "2 3" "4 5 6"
do
echo "a: $a"
done
a: 1
a: 2 3
a: 4 5 6
But the quotes are treated differently when you use a variable:
echo ""1" "2 3" "4 5 6"" > a.txt
cat a.txt
"1" "2 3" "4 5 6"
read aline < a.txt
If you double-quote the variable, you get this:
for b in "$aline"
do
echo "b: $b"
done
b: "1" "2 3" "4 5 6"
And without quotes you get this:
for b in $aline
do
echo "b: $b"
done
b: "1"
b: "2
b: 3"
b: "4
b: 5
b: 6"
Is there a way to get the for to process the contents of the variable as in the first example?
bash for
This what I am trying to get in a bash shell script:
for a in "1" "2 3" "4 5 6"
do
echo "a: $a"
done
a: 1
a: 2 3
a: 4 5 6
But the quotes are treated differently when you use a variable:
echo ""1" "2 3" "4 5 6"" > a.txt
cat a.txt
"1" "2 3" "4 5 6"
read aline < a.txt
If you double-quote the variable, you get this:
for b in "$aline"
do
echo "b: $b"
done
b: "1" "2 3" "4 5 6"
And without quotes you get this:
for b in $aline
do
echo "b: $b"
done
b: "1"
b: "2
b: 3"
b: "4
b: 5
b: 6"
Is there a way to get the for to process the contents of the variable as in the first example?
bash for
bash for
edited Feb 21 at 12:35
filbranden
10.6k21646
10.6k21646
asked Feb 21 at 2:40
Linus HicksLinus Hicks
111
111
Is there another issue that makes you ask this question? Do you have another problem that requires you to disable the shell's standard quote removal, which happens during the evaluation of a command?
– Kusalananda
Feb 21 at 6:43
@Kusalananda yeah, the OP said something to the effect that they simplified the example too much and here were the real thing, but it was cut short at the ":", and the message was immediately deleted. Let's hope that nothing bad happened to him <;-
– mosvy
Feb 21 at 7:19
This is my first time posting a question on this forum, so working out my bugs around posting/commenting. The first answer I got from mosvy gave me enough to work out a solution. The "set -- " seemed to be losing fields. It doesn't like having '#Mi' (no quotes) as one of the fields but once I realized that, I just ran it through sed and now I'm getting what I want. Thanks for the help.
– Linus Hicks
Feb 21 at 7:46
@LinusHicks If you're happy with one or several of the answers, upvote them. If one is solving your issue, accepting it would be the best way of saying "Thank You!" Accepting an answer also indicates to future readers that the answer actually solved the problem.
– Kusalananda
Feb 21 at 8:10
add a comment |
Is there another issue that makes you ask this question? Do you have another problem that requires you to disable the shell's standard quote removal, which happens during the evaluation of a command?
– Kusalananda
Feb 21 at 6:43
@Kusalananda yeah, the OP said something to the effect that they simplified the example too much and here were the real thing, but it was cut short at the ":", and the message was immediately deleted. Let's hope that nothing bad happened to him <;-
– mosvy
Feb 21 at 7:19
This is my first time posting a question on this forum, so working out my bugs around posting/commenting. The first answer I got from mosvy gave me enough to work out a solution. The "set -- " seemed to be losing fields. It doesn't like having '#Mi' (no quotes) as one of the fields but once I realized that, I just ran it through sed and now I'm getting what I want. Thanks for the help.
– Linus Hicks
Feb 21 at 7:46
@LinusHicks If you're happy with one or several of the answers, upvote them. If one is solving your issue, accepting it would be the best way of saying "Thank You!" Accepting an answer also indicates to future readers that the answer actually solved the problem.
– Kusalananda
Feb 21 at 8:10
Is there another issue that makes you ask this question? Do you have another problem that requires you to disable the shell's standard quote removal, which happens during the evaluation of a command?
– Kusalananda
Feb 21 at 6:43
Is there another issue that makes you ask this question? Do you have another problem that requires you to disable the shell's standard quote removal, which happens during the evaluation of a command?
– Kusalananda
Feb 21 at 6:43
@Kusalananda yeah, the OP said something to the effect that they simplified the example too much and here were the real thing, but it was cut short at the ":", and the message was immediately deleted. Let's hope that nothing bad happened to him <;-
– mosvy
Feb 21 at 7:19
@Kusalananda yeah, the OP said something to the effect that they simplified the example too much and here were the real thing, but it was cut short at the ":", and the message was immediately deleted. Let's hope that nothing bad happened to him <;-
– mosvy
Feb 21 at 7:19
This is my first time posting a question on this forum, so working out my bugs around posting/commenting. The first answer I got from mosvy gave me enough to work out a solution. The "set -- " seemed to be losing fields. It doesn't like having '#Mi' (no quotes) as one of the fields but once I realized that, I just ran it through sed and now I'm getting what I want. Thanks for the help.
– Linus Hicks
Feb 21 at 7:46
This is my first time posting a question on this forum, so working out my bugs around posting/commenting. The first answer I got from mosvy gave me enough to work out a solution. The "set -- " seemed to be losing fields. It doesn't like having '#Mi' (no quotes) as one of the fields but once I realized that, I just ran it through sed and now I'm getting what I want. Thanks for the help.
– Linus Hicks
Feb 21 at 7:46
@LinusHicks If you're happy with one or several of the answers, upvote them. If one is solving your issue, accepting it would be the best way of saying "Thank You!" Accepting an answer also indicates to future readers that the answer actually solved the problem.
– Kusalananda
Feb 21 at 8:10
@LinusHicks If you're happy with one or several of the answers, upvote them. If one is solving your issue, accepting it would be the best way of saying "Thank You!" Accepting an answer also indicates to future readers that the answer actually solved the problem.
– Kusalananda
Feb 21 at 8:10
add a comment |
2 Answers
2
active
oldest
votes
If you're OK with having the whole package (variable/arithmetic/command expansion, globbing, etc) on top of quote processing, this will do:
echo '"a b" "x y"' >a.txt
eval "set -- $(<a.txt)"
for b do
printf 'b: %sn' "$b"
done
b: a b
b: x y
Change the $(<a.txt)
to $(cat a.txt)
if you want it to work in a regular shell, not just bash
(or other advanced shells like zsh
or ksh
). You could only use this if you're sure you can control the content of a.txt
, otherwise it will be trivial to exploit your script via splitting with ;
, command expansion, etc.
However, if you just want to pass those arguments to a command, you can use xargs
, which will just process the quotes, without doing any expansion:
xargs <a.txt printf 'b: %sn'
But xargs
will only work with external commands, not with shell functions, will ignore backslashes inside double quotes just like inside single quotes, and won't be able to parse multiline strings.
If these latter limitations are OK, you can still use xargs
as a quote parser via a wrapper or an array:
mapfile -t args < <(xargs <a.txt printf '%sn')
for b in "$args[@]"; do
printf 'b: %sn' "$b"
done
Note that$(<...)
is a ksh operator, copied by zsh and bash (though bash still forks a process, so only save thecat
execution there when using it). See Understanding Bash's Read-a-File Command Substitution for details.
– Stéphane Chazelas
Feb 21 at 6:33
@StéphaneChazelas included both suggestions.
– mosvy
Feb 21 at 6:45
@StéphaneChazelas no, it's not:printf '"anb" c' | xargs
=>xargs: unterminated quote
,xargs: unmatched double quote, etc
. Also the standard says: A string of zero or more non-double-quote ( '"') characters and non- <newline> characters can be quoted by enclosing them in double-quotes. Same thing for single quotes.
– mosvy
Feb 21 at 7:11
Oh yes, you're right, forxargs
a newline is quoted with backslash only. I forgot about that, sorry.
– Stéphane Chazelas
Feb 21 at 7:15
add a comment |
If instead of bash
you're using ksh93
(ksh93
is the shell bash
tries to mimic anyway), you could use the -S
option of its read
builtin which is to read csv (so understands csv-style quoting):
IFS=" " read -rSA array < a.txt
printf 'a: %sn' "$array[@]"
With zsh
, you could use it's z
parameter expansion flag which is used to tokenise the content of a variable as if it was zsh
code (and so understand quoting as zsh
would, but not do the code evaluation that eval
would do) along with the Q
parameter expansion flag to remove one layer of quoting:
IFS= read -r line < a.txt
printf 'a: %sn' "$(Q@)$(z)line"
(the @
parameter expansion flag is to preserve empty elements, reminiscent of ksh
's $array[@]
behaviour).
If a.txt
contains more than one line, with zsh
you can replace the read
command with content=$(<a.txt)
and with ksh93
use read
in a while
loop (each read
invocation potentially reading more than one line if a quoted string spans several line).
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%2f501994%2fread-from-file-then-use-for-to-split-fields-but-honor-quotes%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
If you're OK with having the whole package (variable/arithmetic/command expansion, globbing, etc) on top of quote processing, this will do:
echo '"a b" "x y"' >a.txt
eval "set -- $(<a.txt)"
for b do
printf 'b: %sn' "$b"
done
b: a b
b: x y
Change the $(<a.txt)
to $(cat a.txt)
if you want it to work in a regular shell, not just bash
(or other advanced shells like zsh
or ksh
). You could only use this if you're sure you can control the content of a.txt
, otherwise it will be trivial to exploit your script via splitting with ;
, command expansion, etc.
However, if you just want to pass those arguments to a command, you can use xargs
, which will just process the quotes, without doing any expansion:
xargs <a.txt printf 'b: %sn'
But xargs
will only work with external commands, not with shell functions, will ignore backslashes inside double quotes just like inside single quotes, and won't be able to parse multiline strings.
If these latter limitations are OK, you can still use xargs
as a quote parser via a wrapper or an array:
mapfile -t args < <(xargs <a.txt printf '%sn')
for b in "$args[@]"; do
printf 'b: %sn' "$b"
done
Note that$(<...)
is a ksh operator, copied by zsh and bash (though bash still forks a process, so only save thecat
execution there when using it). See Understanding Bash's Read-a-File Command Substitution for details.
– Stéphane Chazelas
Feb 21 at 6:33
@StéphaneChazelas included both suggestions.
– mosvy
Feb 21 at 6:45
@StéphaneChazelas no, it's not:printf '"anb" c' | xargs
=>xargs: unterminated quote
,xargs: unmatched double quote, etc
. Also the standard says: A string of zero or more non-double-quote ( '"') characters and non- <newline> characters can be quoted by enclosing them in double-quotes. Same thing for single quotes.
– mosvy
Feb 21 at 7:11
Oh yes, you're right, forxargs
a newline is quoted with backslash only. I forgot about that, sorry.
– Stéphane Chazelas
Feb 21 at 7:15
add a comment |
If you're OK with having the whole package (variable/arithmetic/command expansion, globbing, etc) on top of quote processing, this will do:
echo '"a b" "x y"' >a.txt
eval "set -- $(<a.txt)"
for b do
printf 'b: %sn' "$b"
done
b: a b
b: x y
Change the $(<a.txt)
to $(cat a.txt)
if you want it to work in a regular shell, not just bash
(or other advanced shells like zsh
or ksh
). You could only use this if you're sure you can control the content of a.txt
, otherwise it will be trivial to exploit your script via splitting with ;
, command expansion, etc.
However, if you just want to pass those arguments to a command, you can use xargs
, which will just process the quotes, without doing any expansion:
xargs <a.txt printf 'b: %sn'
But xargs
will only work with external commands, not with shell functions, will ignore backslashes inside double quotes just like inside single quotes, and won't be able to parse multiline strings.
If these latter limitations are OK, you can still use xargs
as a quote parser via a wrapper or an array:
mapfile -t args < <(xargs <a.txt printf '%sn')
for b in "$args[@]"; do
printf 'b: %sn' "$b"
done
Note that$(<...)
is a ksh operator, copied by zsh and bash (though bash still forks a process, so only save thecat
execution there when using it). See Understanding Bash's Read-a-File Command Substitution for details.
– Stéphane Chazelas
Feb 21 at 6:33
@StéphaneChazelas included both suggestions.
– mosvy
Feb 21 at 6:45
@StéphaneChazelas no, it's not:printf '"anb" c' | xargs
=>xargs: unterminated quote
,xargs: unmatched double quote, etc
. Also the standard says: A string of zero or more non-double-quote ( '"') characters and non- <newline> characters can be quoted by enclosing them in double-quotes. Same thing for single quotes.
– mosvy
Feb 21 at 7:11
Oh yes, you're right, forxargs
a newline is quoted with backslash only. I forgot about that, sorry.
– Stéphane Chazelas
Feb 21 at 7:15
add a comment |
If you're OK with having the whole package (variable/arithmetic/command expansion, globbing, etc) on top of quote processing, this will do:
echo '"a b" "x y"' >a.txt
eval "set -- $(<a.txt)"
for b do
printf 'b: %sn' "$b"
done
b: a b
b: x y
Change the $(<a.txt)
to $(cat a.txt)
if you want it to work in a regular shell, not just bash
(or other advanced shells like zsh
or ksh
). You could only use this if you're sure you can control the content of a.txt
, otherwise it will be trivial to exploit your script via splitting with ;
, command expansion, etc.
However, if you just want to pass those arguments to a command, you can use xargs
, which will just process the quotes, without doing any expansion:
xargs <a.txt printf 'b: %sn'
But xargs
will only work with external commands, not with shell functions, will ignore backslashes inside double quotes just like inside single quotes, and won't be able to parse multiline strings.
If these latter limitations are OK, you can still use xargs
as a quote parser via a wrapper or an array:
mapfile -t args < <(xargs <a.txt printf '%sn')
for b in "$args[@]"; do
printf 'b: %sn' "$b"
done
If you're OK with having the whole package (variable/arithmetic/command expansion, globbing, etc) on top of quote processing, this will do:
echo '"a b" "x y"' >a.txt
eval "set -- $(<a.txt)"
for b do
printf 'b: %sn' "$b"
done
b: a b
b: x y
Change the $(<a.txt)
to $(cat a.txt)
if you want it to work in a regular shell, not just bash
(or other advanced shells like zsh
or ksh
). You could only use this if you're sure you can control the content of a.txt
, otherwise it will be trivial to exploit your script via splitting with ;
, command expansion, etc.
However, if you just want to pass those arguments to a command, you can use xargs
, which will just process the quotes, without doing any expansion:
xargs <a.txt printf 'b: %sn'
But xargs
will only work with external commands, not with shell functions, will ignore backslashes inside double quotes just like inside single quotes, and won't be able to parse multiline strings.
If these latter limitations are OK, you can still use xargs
as a quote parser via a wrapper or an array:
mapfile -t args < <(xargs <a.txt printf '%sn')
for b in "$args[@]"; do
printf 'b: %sn' "$b"
done
edited Feb 21 at 6:40
answered Feb 21 at 4:07
mosvymosvy
8,2871732
8,2871732
Note that$(<...)
is a ksh operator, copied by zsh and bash (though bash still forks a process, so only save thecat
execution there when using it). See Understanding Bash's Read-a-File Command Substitution for details.
– Stéphane Chazelas
Feb 21 at 6:33
@StéphaneChazelas included both suggestions.
– mosvy
Feb 21 at 6:45
@StéphaneChazelas no, it's not:printf '"anb" c' | xargs
=>xargs: unterminated quote
,xargs: unmatched double quote, etc
. Also the standard says: A string of zero or more non-double-quote ( '"') characters and non- <newline> characters can be quoted by enclosing them in double-quotes. Same thing for single quotes.
– mosvy
Feb 21 at 7:11
Oh yes, you're right, forxargs
a newline is quoted with backslash only. I forgot about that, sorry.
– Stéphane Chazelas
Feb 21 at 7:15
add a comment |
Note that$(<...)
is a ksh operator, copied by zsh and bash (though bash still forks a process, so only save thecat
execution there when using it). See Understanding Bash's Read-a-File Command Substitution for details.
– Stéphane Chazelas
Feb 21 at 6:33
@StéphaneChazelas included both suggestions.
– mosvy
Feb 21 at 6:45
@StéphaneChazelas no, it's not:printf '"anb" c' | xargs
=>xargs: unterminated quote
,xargs: unmatched double quote, etc
. Also the standard says: A string of zero or more non-double-quote ( '"') characters and non- <newline> characters can be quoted by enclosing them in double-quotes. Same thing for single quotes.
– mosvy
Feb 21 at 7:11
Oh yes, you're right, forxargs
a newline is quoted with backslash only. I forgot about that, sorry.
– Stéphane Chazelas
Feb 21 at 7:15
Note that
$(<...)
is a ksh operator, copied by zsh and bash (though bash still forks a process, so only save the cat
execution there when using it). See Understanding Bash's Read-a-File Command Substitution for details.– Stéphane Chazelas
Feb 21 at 6:33
Note that
$(<...)
is a ksh operator, copied by zsh and bash (though bash still forks a process, so only save the cat
execution there when using it). See Understanding Bash's Read-a-File Command Substitution for details.– Stéphane Chazelas
Feb 21 at 6:33
@StéphaneChazelas included both suggestions.
– mosvy
Feb 21 at 6:45
@StéphaneChazelas included both suggestions.
– mosvy
Feb 21 at 6:45
@StéphaneChazelas no, it's not:
printf '"anb" c' | xargs
=> xargs: unterminated quote
, xargs: unmatched double quote, etc
. Also the standard says: A string of zero or more non-double-quote ( '"') characters and non- <newline> characters can be quoted by enclosing them in double-quotes. Same thing for single quotes.– mosvy
Feb 21 at 7:11
@StéphaneChazelas no, it's not:
printf '"anb" c' | xargs
=> xargs: unterminated quote
, xargs: unmatched double quote, etc
. Also the standard says: A string of zero or more non-double-quote ( '"') characters and non- <newline> characters can be quoted by enclosing them in double-quotes. Same thing for single quotes.– mosvy
Feb 21 at 7:11
Oh yes, you're right, for
xargs
a newline is quoted with backslash only. I forgot about that, sorry.– Stéphane Chazelas
Feb 21 at 7:15
Oh yes, you're right, for
xargs
a newline is quoted with backslash only. I forgot about that, sorry.– Stéphane Chazelas
Feb 21 at 7:15
add a comment |
If instead of bash
you're using ksh93
(ksh93
is the shell bash
tries to mimic anyway), you could use the -S
option of its read
builtin which is to read csv (so understands csv-style quoting):
IFS=" " read -rSA array < a.txt
printf 'a: %sn' "$array[@]"
With zsh
, you could use it's z
parameter expansion flag which is used to tokenise the content of a variable as if it was zsh
code (and so understand quoting as zsh
would, but not do the code evaluation that eval
would do) along with the Q
parameter expansion flag to remove one layer of quoting:
IFS= read -r line < a.txt
printf 'a: %sn' "$(Q@)$(z)line"
(the @
parameter expansion flag is to preserve empty elements, reminiscent of ksh
's $array[@]
behaviour).
If a.txt
contains more than one line, with zsh
you can replace the read
command with content=$(<a.txt)
and with ksh93
use read
in a while
loop (each read
invocation potentially reading more than one line if a quoted string spans several line).
add a comment |
If instead of bash
you're using ksh93
(ksh93
is the shell bash
tries to mimic anyway), you could use the -S
option of its read
builtin which is to read csv (so understands csv-style quoting):
IFS=" " read -rSA array < a.txt
printf 'a: %sn' "$array[@]"
With zsh
, you could use it's z
parameter expansion flag which is used to tokenise the content of a variable as if it was zsh
code (and so understand quoting as zsh
would, but not do the code evaluation that eval
would do) along with the Q
parameter expansion flag to remove one layer of quoting:
IFS= read -r line < a.txt
printf 'a: %sn' "$(Q@)$(z)line"
(the @
parameter expansion flag is to preserve empty elements, reminiscent of ksh
's $array[@]
behaviour).
If a.txt
contains more than one line, with zsh
you can replace the read
command with content=$(<a.txt)
and with ksh93
use read
in a while
loop (each read
invocation potentially reading more than one line if a quoted string spans several line).
add a comment |
If instead of bash
you're using ksh93
(ksh93
is the shell bash
tries to mimic anyway), you could use the -S
option of its read
builtin which is to read csv (so understands csv-style quoting):
IFS=" " read -rSA array < a.txt
printf 'a: %sn' "$array[@]"
With zsh
, you could use it's z
parameter expansion flag which is used to tokenise the content of a variable as if it was zsh
code (and so understand quoting as zsh
would, but not do the code evaluation that eval
would do) along with the Q
parameter expansion flag to remove one layer of quoting:
IFS= read -r line < a.txt
printf 'a: %sn' "$(Q@)$(z)line"
(the @
parameter expansion flag is to preserve empty elements, reminiscent of ksh
's $array[@]
behaviour).
If a.txt
contains more than one line, with zsh
you can replace the read
command with content=$(<a.txt)
and with ksh93
use read
in a while
loop (each read
invocation potentially reading more than one line if a quoted string spans several line).
If instead of bash
you're using ksh93
(ksh93
is the shell bash
tries to mimic anyway), you could use the -S
option of its read
builtin which is to read csv (so understands csv-style quoting):
IFS=" " read -rSA array < a.txt
printf 'a: %sn' "$array[@]"
With zsh
, you could use it's z
parameter expansion flag which is used to tokenise the content of a variable as if it was zsh
code (and so understand quoting as zsh
would, but not do the code evaluation that eval
would do) along with the Q
parameter expansion flag to remove one layer of quoting:
IFS= read -r line < a.txt
printf 'a: %sn' "$(Q@)$(z)line"
(the @
parameter expansion flag is to preserve empty elements, reminiscent of ksh
's $array[@]
behaviour).
If a.txt
contains more than one line, with zsh
you can replace the read
command with content=$(<a.txt)
and with ksh93
use read
in a while
loop (each read
invocation potentially reading more than one line if a quoted string spans several line).
edited Feb 21 at 7:08
answered Feb 21 at 6:27
Stéphane ChazelasStéphane Chazelas
310k57584945
310k57584945
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.
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%2f501994%2fread-from-file-then-use-for-to-split-fields-but-honor-quotes%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
Is there another issue that makes you ask this question? Do you have another problem that requires you to disable the shell's standard quote removal, which happens during the evaluation of a command?
– Kusalananda
Feb 21 at 6:43
@Kusalananda yeah, the OP said something to the effect that they simplified the example too much and here were the real thing, but it was cut short at the ":", and the message was immediately deleted. Let's hope that nothing bad happened to him <;-
– mosvy
Feb 21 at 7:19
This is my first time posting a question on this forum, so working out my bugs around posting/commenting. The first answer I got from mosvy gave me enough to work out a solution. The "set -- " seemed to be losing fields. It doesn't like having '#Mi' (no quotes) as one of the fields but once I realized that, I just ran it through sed and now I'm getting what I want. Thanks for the help.
– Linus Hicks
Feb 21 at 7:46
@LinusHicks If you're happy with one or several of the answers, upvote them. If one is solving your issue, accepting it would be the best way of saying "Thank You!" Accepting an answer also indicates to future readers that the answer actually solved the problem.
– Kusalananda
Feb 21 at 8:10