I could use some suggestions, this probably isn't the most elegant way to do this but it's what came to mind. Let me add a couple snippets for clarity.
week1="01-\(04\|05\|06\|07\|08\|09\|10\)-2016"
week2="01-\(11\|12\|13\|14\|15\|16\|17\)-2016"
week3="01-\(18\|19\|20\|21\|22\|23\|24\)-2016"
week4="01-\(25\|26\|27\|28\|29\|30\|31\)-2016"
week5="02-\(01\|02\|03\|04\|05\|06\|07\)-2016"
I have a text file that has dates in each line, for example
293232343;01-02-2016;blah;more blah
234872348;02-01-2016;blah;extra blah
I am trying to create a loop so I can grab different data depending on the calendar week.
current_week=`date +%W`
for (( c=1; c<=$current_week; c++ ))
do
sort -k2 archive.txt|tr "\\t" ";"|grep $week$c|while read line; do
My problem is that $week$c doesn't actually translate to $week1, $week2, etc. Any easy solutions here? Thanks in advance.
From man bash:
If the first character of parameter is an exclamation point, a level
of
variable indirection is introduced. Bash uses the value of the vari-
able formed from the rest of parameter as the name of the variable;
this variable is then expanded and that value is used in the rest of
the substitution, rather than the value of parameter itself. This is
known as indirect expansion. The exceptions to this are the expansions
of ${!prefix*} and ${!name[#]} described below. The exclamation point
must immediately follow the left brace in order to introduce indirec-
tion.
Then, what you need is
var="week$c"
... grep "${!var}" ...
Related
The Rundeck docs give the example of defining a message option (parameter) which can then be referred to by the script in a number of ways, including
echo message=#option.message# ;# replacement token
We use this syntax and it seems fine, but I have no idea what those two #s actually mean to bash; I can't find mention of anything beyond $#, or anything relevant for the "replacement token" in the comment.
Per the docs you linked, that is a "replacement token" handled by Rundeck. That is, Rundeck replaces the #...# before passing the command to bash. Consequently, they don't mean anything to bash :) . Specifically, the docs say:
Inline Script workflow steps that contain a token expansion will be expanded into a temporary file, and the temp file will contain the plaintext option value.
So bash sees the temp file post-expansion, without the #...# sequences and with their values as literal text.
The docs also note that "If the option is blank or unset the token will be replaced with a blank string." Therefore, the whole #...# sequence will disappear if a particular token is not defined.
See also this section on script usage and this section on context variables in the docs.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
Example of what I want to combine:
sVar=$(whoami)
sVar=${sVar^}
sVar=${sVar::1}
Output:
Uppercase first character of username
Requirements:
One-liner
Do the rest of the processing with parameter substitutions except for the initial command substitution above $(whoami)
I realize this can be done with tr, sed, awk, printf, cut, etc.; but that is not the point of the question.
Any help is appreciate!
This isn't the real code or anything indicative of what I am wanting to actually do. I will often default (or try to) to using just one command over concatenating multiple commands.
I've seen other posts state that concatenating within the braces are not possible, but I know that everything is possible.
Please don't:
Reference other posts as duplicate that say it's impossible
One liner:
sVar=$(whoami) sVar=${sVar^} sVar=${sVar::1}
It may not be what you were looking for, but it is certainly a single command and uses parameter substitutions. A single command can consist of multiple variable assignments, in which case they are performed left to right.
The subject of a parameter substitution is a variable name, an indirection (a ! followed by a variable name), or a subscript expression (a variable name -- not an indirection -- followed by a subscript within [ and ]. That's a bit limited, to be sure, but that's bash. (Posix shell is even more restrictive; it has no indirection nor arrays, and fewer types of expansion.)
Posix wording from XCU, emphasis added:
When a given simple command is required to be executed… the following expansions, assignments, and redirections shall all be performed from the beginning of the command text to the end:
…
Each variable assignment shall be expanded for tilde expansion, parameter expansion, command substitution, arithmetic expansion, and quote removal prior to assigning the value.
From https://stackoverflow.com/a/10820494/1764881, I know that the standard way of doing it seems to be:
var="SAMPLE$i"
echo ${!var}
But, I can't seem to do any of these following forms. They all failed:
echo ${!SAMPLE$i}
echo ${!"SAMPLE$i"}
I read the bash man page, but I still couldn't understand. Is it true that the first form is the only form accepted?
Yes. The underlying logic is that all parameter expansions take a single, literal word as the name of the parameter to expand, and any additional operator does something to the result. ! is no exception; var is expanded as usual, but the result is expanded again.
(As an aside, even arrays follow this rule. It might seem that something like ${array[2]%foo} applies two operators to array, but really array[2] is treated as the name of a single parameter. There is a little difference, as the index is allowed to be an arbitrary arithmetic expression rather than a literal number.)
(And for completeness, I should mention the actual exceptions, ${!prefix*} and ${!name[*]}, which confusingly use the same operator ! for querying variables themselves. The first lists variable names starting with the same prefix; the second lists the keys of the named array.)
I'm looking over a script (which has been used successfully in the past) which contains the following:
node=1
while :
do
userKey=WEB_${node}_USER
userVal=`echo ${!userKey}`
I have not been able to figure out why an exclamation point would be added to a variable reference like this. What purpose does "!" serve in this context?
It's rare for me to do much scripting so if I am missing any details please let me know and I will try to provide more information. I have not been able to find this answer elsewhere.
Thanks in advance!
It's called indirect parameter expansion. Where $userKey expands to the value of the variable userKey, ${!userKey} expands to the value of the variable whose name is the value of userKey. Since usrKey has the value WEB_1_USER (given the current value of $node, ${!userKey} expands to the same result as $WEB_1_USER.
Its use is somewhat rare, since in many cases (including, it appears, here) an array WEB_USER of user names would be clearer than a set of numbered variables.
WEB_USER=(alice bob charlie)
node=1
while :
do
userVal=${WEB_USER[node]}
In bash, I thought that the only characters that retained their meta-character status inside double quotes were the dollar sign ($), the back-tick (`) and the backslash (\).
I want to parse the following word in shell script
VERSION=METER1.2.1
Here i want to split it as two words as
WORD1=METER
WORD2=1.2.1
Let me help how to parse it?
Far more efficient than using external tools such is sed is bash's built-in parameter expansion support. For instance, if you want the name variable to contain everything until the first number, and the numbers variable to contain everything after the last alpha character:
version=METER1.2.1
name=${version%%[0-9]*}
numbers=${version##*[[:alpha:]]}
To understand this, see the BashFAQ entry on string manipulation in general, or the BashFAQ entry on parameter expansion in particular.