Consider this task : With a one line command save all usernames transformed into CAPITALS in a bash array called USERNAMES. Capitalize using bash variable expansion.
If not for the the one line limitation, I would just use
USERNAMES=($(ls /home)) # simplified for purposes of this question, returns (user1 user2 ...)
USERNAMES=(${USERNAMES[*]^^}) # must return (USER1 USER2 ...)
but all attempts at nesting the first assignment to the variable expansion like USERNAMES=${($(ls /home))^^}
or similar lead to 'bad substitution' error. I'm using bash 4.4.20(1)-release.
CodePudding user response:
I use /*
because you should not parse ls
and I have only one dir in home.
USERNAMES=(/*); USERNAMES=("${USERNAMES[@]^^}")
readarray -t USERNAMES < <(printf "%s\n" /* | sed 's/.*/\U&/')
readarray -t USERNAMES < <(printf "%s\n" /* | tr '[:lower:]' '[:upper:]')
# or zero separated
readarray -t -d '' USERNAMES < <(printf "%s\0" /* | sed -z 's/.*/\U&/')
readarray -t -d '' USERNAMES < <(printf "%s\0" /* | tr -z '[:lower:]' '[:upper:]')
# Or another program
readarray -t USERNAMES < <(python -c 'import os,sys;[print(x.upper()) for x in os.listdir(sys.argv[1])]' /)
# You can hash _any_ multiline script to base64 and then execute it. It will be one line.
base64 -d <<<IyEvYmluL2Jhc2gKVVNFUk5BTUVTPSgkKGxzIC9ob21lKSkgIyBzaW1wbGlmaWVkIGZvciBwdXJwb3NlcyBvZiB0aGlzIHF1ZXN0aW9uLCByZXR1cm5zICh1c2VyMSB1c2VyMiAuLi4pClVTRVJOQU1FUz0oJHtVU0VSTkFNRVNbKl1eXn0pICMgbXVzdCByZXR1cm4gKFVTRVIxIFVTRVIyIC4uLikKZWNobyAiJHtVU0VSTkFNRVNbQF19Igo= | bash
Notes:
- do not parse ls! https://unix.stackexchange.com/questions/128985/why-not-parse-ls-and-what-to-do-instead
- Do not use
($(...))
. Usereadarray
- When working with arrays, properly quote and use
[@]
. It's"${USERNAMES[@]}"
.
CodePudding user response:
If this is for homework, I'm guessing your teacher is looking for
users=($(ls /home | tr a-z A-Z))
or perhaps, to avoid parsing ls
(but consequently not strictly sticking to the "one command only" requirement)
users=($(cd /home && echo * | tr a-z A-Z))
Bash has built-in parameter expansion facilities but those necessarily require two commands - one to get the value and another to perform a parameter expansion on it.