Let's say I have:
template=$(<template.txt)
replacement=$(<replacement.txt)
How do I then store in a third variable the value of template, with "REPLACE_ME" replaced with the content of replacement, no matter what template and replacement contain?
Try this with GNU bash 4:
foo="${template//REPLACE_ME/$replacement}"
Related
I have a string like : 2021_03_19/ 19-Mar-2021 11:55 -
stored in a variable a
I tried to extract from it the sequence: 2021_03_19, the second one after /"> sequence with the following script:
a=${a##'/">'}
a=${a%%'/</a'}
But the final result is the same string as the input.
The pattern in the parameter expansion needs to match the entire string you want to remove. You are trying to trim the literal prefix /"> but of course the string does not begin with this string, so the parameter expansion does nothing.
Try
a=${a##*'/">'}
a=${a%%'/</a'*}
The single quotes are kind of unusual; I would perhaps instead backslash-escape each metacharacter which should be matched literally.
a=${a##*/\"\>}
a=${a%%/\</a*}
You have to match the before and after pattern too.
a=${a##*'/">'}
a=${a%%'/</a'*}
You could use:
a='2021_03_19/ 19-Mar-2021 11:55 -'
b=${a#*>}
c=${b%%/<*}
Based on Extract substring in Bash
In your example you want to select based on 3 characters but have ##, not ###. I did try that but doesn't seem to work either. So, therefore an alternative solution.
I have a program parsing two files and comparing them looking for conflicts between the two and allowing the user to decide what action to take. As a result, I need to be able to parse the lines below. If a string contains { or } when using pattern replacement parameter expansion it will cause an error.
I was looking for a potential work around for the following lines
F=TSM_CLASS="Test text {class}"
newstring=${F//{class}/\\{class\\}}
Results:
echo $newstring
TSM_CLASS="Test text }/\{class\}}"
${F//{class} is a complete parameter expansion which replaces every instance of {class in F's value with empty string. To embed braces in the pattern and/or the replacement string, you need to quote them.
$ F=TSM_CLASS="Test text {class}"
$
$ echo "${F//{class\}/\\{class\\\}}"
TSM_CLASS=Test text \{class\}
I'm trying to extract a tag value of an HTML node that I already have in a variable.
I'm currently using Zsh but I'm trying to make it work in Bash as well.
The current variable has the value:
<span class="alter" fill="#ffedf0" data-count="0" data-more="none"/>
and I would like to get the value of data-count (in this case 0, but could be any length integer).
I have tried using cut, sed and the variables expansion as explained in this question but I haven't managed to adapt the regexs, or maybe it has to be done differently for Zsh.
There is no reason why sed would not work in this situation. For your specific case, I would do something like this:
sed 's/.*data-count="\([0-9]*\)".*/\1/g' file_name.txt
Basically, it just states that sed is looking for the a pattern that contains data-count=, then saves everything within the paranthesis \(...\) into \1, which is subsequently printed in place of the match (full line due to the .*)
Could you please try following.
awk 'match($0,/data-count=[^ ]*/){print substr($0,RSTART+12,RLENGTH-13)}' Input_file
Explanation: Using match function of awk to match regex data-count=[^ ]* means match everything from data-count till a space comes, if this regex is TRUE(a match is found) then out of the box variables RSTART and RLENGTH will be set. Later I am printing current line's sub-string as per these variables values to get only value of data-count.
With sed could you please try following.
sed 's/.*data-count=\"\([^"]*\).*/\1/' Input_file
Explanation: Using sed's capability of group referencing and saving regex value in first group after data-count=\" which is its length, then since using s(substitution) with sed so mentioning 1 will replace all with \1(which is matched regex value in temporary memory, group referencing).
As was said before, to be on the safe side and handle any syntactically valid HTML tag, a parser would be strongly advised. But if you know in advance, what the general format of your HTML element will look like, the following hack might come handy:
Assume that your variable is called "html"
html='<span class="alter" fill="#ffedf0" data-count="0" data-more="none"/>'
First adapt it a bit:
htmlx="tag ${html%??}"
This will add the string tag in front and remove the final />
Now make an associative array:
declare -A fields
fields=( ${=$(tr = ' ' <<<$htmlx)} )
The tr turns the equal sign into a space and the ${= handles word splitting. You can now access the values of your attributes by, say,
echo $fields[data-count]
Note that this still has the surrounding double quotes. Yuo can easily remove them by
echo ${${fields[data-count]%?}#?}
Of course, once you do this hack, you have access to all attributes in the same way.
I have a simple sed script and I am replacing a bunch of lines in my application dynamically with a variable, the variable is a list of strings.My function works but does not keep the original indentation.the function deletes the line if it contains the certain string and replaces the line with a completely new line, I could not do a replace due to certain syntax restrictions.
How do I keep my original indentation when the line is replaced
Can I capitalize my variable and remove the underscore on the fly, i.e. the title is a capitalize and underscore removed version of the variableName, the list of items in the variable array is really long so I am trying to do this in one shot.
Ex: I want report_type -> Report Type done mid process
Is there a better way to solve this with sed? Thanks for any inputs much appreciated.
sed function is as follows
variableName=$1
sed -i "/name\=\"${variableName}\.name\" value\=model\.${variableName}\.name options\=\#lists\./c\\{\{\> \_dropdown title\=\"${variableName}\" required\=true name\=\"${variableName}\"\}\}" test
SAMPLE INPUT
{{> _select title="Report Type" required=true name="report_type.name" value=model.report_type.name options=#lists.report_type}}
SAMPLE EXPECTED OUPUT
{{> _dropdown title="Report Type" required=true name="report_type" value=model.report_type.name}}
sample input variable
report_type
Try this:
sed -E "s/^(\s+).*name\=\"(report_type)\.name\" value\=model\.report_type\.name options\=\#lists\..*$/\1\{\{\> \_dropdown title\=\"\2\" required\=true name\=\"\2\"\}\}/;T;s/\"(\w+)_(\w+)\"/\"\u\1 \u\2\"/g" input.txt > output.txt
I used "report_type" instead of ${variableName} for testing as an sed one-liner.
Please change back to ${variableName}.
Then go back to using -i (in addition to -E, which is for extended regex).
I am not sure whether I can do it without extended regex, let me know if that is necessary.
use s/// to replace fine tuned line
first capture group for the white space making the indentation
second capture group for the variable name
stop if that did not replace anything, T;
another s///
look for something consisting of only letters between "",
with a "_" between two parts,
seems safe enough because this step is only done on the already replaced line
replace by two parts, without "_"
\u for making camel case
Note:
Doing this on your sample input creates two very similar lines.
I assume that is intentional. Otherwise please provide desired output.
Using GNU sed version 4.2.1.
Interesting line of output:
{{> _dropdown title="Report Type" required=true name="Report Type"}}
I want to do a search and replace on a line with specific line number. However, I want to be able to use a variable for the Line Number itself.
For instance, if I wanted to replace the number 4 with a number 5 on line 180. I would use the following code.
sed '180 s/4/5/' file
My Question is how do I use a variable for the line number?
sed '$variable s/4/5/' file
#gniourf_gniourf's comment contains the crucial pointer: use double quotes around your sed program in order to reference shell variables (the shell doesn't interpret (expand) single-quoted strings in any way).
Note that sed programs are their own world - they have NO concept of variables, so the only way to use variables is to use a double-quoted string evaluated by the shell containing references to shell variables.
As a result, you must \-escape characters that you want the shell to ignore and pass through to sed to see, notably $ as \$.
In your specific case, however, nothing needs escaping.
Thus, as #gniourf_gniourf states in his comment, use:
sed "$variable s/4/5/" file
Afterthought:
Alternatively, the core of your sed program can remain single-quoted, with only the shell-variable references spliced in as double-quoted strings; note that no spaces are allowed between the string components, as the entire expression must evaluate to a single string:
sed "$variable"' s/4/5/' file
While in this specific case you could get away without the double quotes around the variable reference, it's generally safer to use them, so as to avoid unwanted shell expansions (such as word splitting) that could alter or even break the command.
You could just leave the variable outside of the quotes
sed $variable's/4/5/' file
Note that there cannot be a space between the variable and beginning quote though
You can do it with awk
awk 'NR==l {sub(/4/,"5")}1' l="$variable" file