In bash, I'd like to get the name of the one-and-only subfolder of a
:
cd /tmp; mkdir -p a/b; v=$(ls -1 a); echo "$v"
outputs:
b
Which is what I wanted.
This works, because I know there will be only one-and-only subfolder inside a
.
Feel free to assume this is guaranteed in all cases in my scenario.
What I feel uneasy about, is this recommendation from Bash pitfalls
In addition to this, the use of ls is just plain unnecessary.
It's an external command whose output is intended specifically
to be read by a human, not parsed by a script.
This is even more intimidating and lapidary (from the same link as above):
parsing the output of ls -- a utility whose output should never ever be parsed.
It resonates with me but this, an attempt at using bash globbing, obv. does not work:
cd /tmp; mkdir -p a/b; v=a/*; echo "$v"
outputs:
a/*
Sadness.
So, how can I get globbing for a variable assignment?
I think I know how to leverage globbing outside of assignment..
for d in a/*; do echo "$(basename $d)"; done
outputs:
b
"The right answer" (TM).
Could you kindly teach me how to do this right and explain the principle behind it too, please?
** NOTE: I don't like the output of this command:**
cd /tmp; w='name with blanks'; mkdir -p "$w/b"; v=$(echo "$w"/*); echo "$v"
which is:
name with blanks/b
I'd like to just get:
b
do I have to use basename
afterwards, or could I get b
directly, somehow?
Pretty sure I wrote that pitfalls sentence. Anyway... yours fails because brace expansions, globs, and word-splitting don't apply to scalar assignments.
printf -v v %s */
And a little-known trick that will only work using the coreutils printf(1)
(assuming there were multiple directories).
v=$(LC_COLLATE=C; /usr/bin/printf '%s\c' */)
Or alternatively, this is probably closest to what you're after (GNU find):
v=$(find . -maxdepth 1 -type d -name '[^.]?*' -printf %f -quit)
See also: http://mywiki.wooledge.org/ParsingLs
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With