Issue assigning a SED to a variable - sed

I am working on a BSD machine and what I am attempting to do is assign a variable the output from a SED command that uses a variable as input. Been working on this for 3 days, tried multiple different things, and always end up with './subscript: ${sed ...}: Bad substitution' error. Any help is greatly appreciated.
TMPEX=${sed "s/\\\\\\/\\\\/g" <<$TMPEX}
TEMPEX originally contains
C:\\Windows\\System32\\wininit.exe
and I would like to replace the double backslashes with single backslashes so that TMPEX contains:
C:\Windows\System32\wininit.exe
What am I missing?

Using sed and a shell which understands here-strings:
TMPEX="$(sed 's/\\\\/\\/g' <<< "$TMPEX")"
Or, still using sed, for a shell which does not understand here-strings:
TMPEX="$(echo "$TMPEX" | sed 's/\\\\/\\/g')"
Or even better, if the shell understands pattern substitution:
TMPEX="${TMPEX//\\\\/\\}"

Related

sed - replace jira macro in confluence space

Think i'm very close to my solution but i don't see what's wrong with this expression. I checked this expression within an editor, which works fine. But same should work with sed, so that i can run it with a shell script.
What i did.
I exported a Confluence Space and like to import to another Confluence. This confluence does not know the JIRA Server as an Application Link and it will not get.
So that's why i want to replace the macro with a link.
<ac:structured-macro ac:name="jira"><ac:parameter ac:name="columns">key,summary,type,created,updated,due,assignee,reporter,priority,status,resolution</ac:parameter><ac:parameter ac:name="server">JIRA</ac:parameter><ac:parameter ac:name="serverId">797a864e-7adf-3e88-ae1f-f35e5aade3f4</ac:parameter><ac:parameter ac:name="key">IT-1234</ac:parameter></ac:structured-macro>
I tried the following to replace the macro. But didn't work yet. Can somebody help me with this expression, and explain what i'm doing wrong?
sed -i -E 's/<ac:structured-macro ac:name="jira">.*?((?:IT|BI)-[0-9]+).*?<\/ac:structured-macro>/http:\/\/www.myconfluence.com\/browse\/\1/gI' "confluence-space/entities.xml"
I get the result:
sed: -e expression #1, char 130: Invalid preceding regular expression.
Thanks in advance.
You can't use (?:x)(non-capturing groups) syntax with sed.
(? will search for zero or one occurrence of... nothing because ( is not interpreted as a litteral character but as an opening capturing group.
Try this:
sed -i -E 's/<ac:structured-macro ac:name="jira">.*?((IT|BI)-[0-9]*).*<\/ac:structured-macro>/http:\/\/www.myconfluence.com\/browse\/\1/g' file

The perl -pe command

So I've done a research about the perl -pe command and I know that it takes records from a file and creates an output out of it in a form of another file. Now I'm a bit confused as to how this line of command works since it's a little modified so I can't really figure out what exactly is the role of perl pe in it. Here's the command:
cd /usr/kplushome/entities/Standalone/config/webaccess/WebaccessServer/etc
(PATH=/usr/ucb:$PATH; ./checkall.sh;) | perl -pe "s,^, ,g;"
Any idea how it works here?
What's even more confusing in the above statement is this part : "s,^, ,g;"
Any help would be much appreciated. Let me know if you guys need more info. Thank you!
It simply takes an expression given by the -e flag (in this case, s,^, ,g) and performs it on every line of the input, printing the modified line (i.e. the result of the expression) to the output.
The expression itself is something called a regular expression (or "regexp" or "regex") and is a field of learning in and of itself. Quick googles for "regular expression tutorial" and "getting started with regular expressions" turn up tons of results, so that might be a good place to start.
This expression, s,^, ,g, adds ten spaces to the start of the line, and as I said earlier, perl -p applies it to every line.
"s,^, ,g;"
s is use for substitution. syntax is s/somestring/replacement/.
In your command , is the delimiter instead of /.
g is for work globally, means replace all occurrence.
For example:
perl -p -i -e "s/oldstring/newstring/g" file.txt;
In file.txt all oldstring will replace with newstring.
i is for inplace file editing.
See these doc for information:
perlre
perlretut
perlop

How to use variable in Linux sed command

I have already read some topic but there is no similar to mine.
I need to pass to sed command with a $value but its too hard :
sed "1,$valued" filename.txt
like
sed "1,4d" filename.txt
How can i do that ?
That's trying to use a variable called $valued.
So you can either:
1,${value}d.
Or set $valued to 4d.
Easiest way:
sed "1,$value"d filename.txt
$value is a shell variable (I assume you were already doing that). So you just needed a way to separate the variable name from what comes next (to avoid evaluating $valued). Quote marks do the job just fine since the shell removes them before calling sed.

How to get sed to include a double \\ that's included in a variable

I'm writing a script in bash that performs a simple transform of a file we'll call storage.config.
Parameters are passed from our automation system (VCAC\AppD) to our action script, which performs the transform using sed.
To keep things simple, I'll use the following example
storage.config - To be transformed
url=jdbc:sqlserver://#myDB
Transform Script
myDB='serverxyz\\instance'
sed -i -e "s,#myDB,$myDB,g" storage.config
I would expect the resulting storage.config to look like this;
url=jdbc:sqlserver://serverxyz\\instance
However, it looks like this instead;
url=jdbc:sqlserver://serverxyz\instance
I've read through the answers on this site, as well as others. And have found a lot of useful information on how to include variable, single vs. double quotes, but nothing on how to retain a double \ in a variable. I'd like to get sed to interpret correctly, rather than type something like;
myDB='serverxyz\\\\instance'
This value will be entered by Solutions Engineers, who might enter improperly as they don't recognize it as a valid SQL instance.
sed is interpreting it correctly.
You are sticking \\ in the replacement as a literal string.
sed doesn't know it was a variable from somewhere else and not just typed out manually.
Escaping it is the answer.
You can do it at expansion time with ${myDB//\\/\\\\} if you want though.
Additionally, as #abesto quite correctly indicated in his answer, you are loosing the doubled slash before sed even sees it. Use single quotes in your assignment to preserve it.
myDB='server\\instance'
The double \ doesn't even get as far as sed. Your shell sees \\, and reads it as "oh, you want a \, because you escaped it". You can try it out like this:
myDB="serverxyz\\instance"
echo "$myDB"
# output: serverxyz\instance
So in conclusion (Thanks to all that responded. Special thanks to #Etan);
myDB='serverxyz\\instance'
sed -i -e "s,#myDB,${myDB//\\/\\\\},g" storage.config
The above code results in the proper translation\transform of my storage.config file. The resulting storage.config is as follows;
url=jdbc:sqlserver://serverxyz\\instance

How to use sed to delete lines which have certain pattern and at some specific line range?

This is the command working for me:
sed "50,99999{/^\s*printf/d}" the_file
So this command delete all the lines between 50 and 99999 which have "printf" in it and there is only whitespace before printf at the line.
Now my questions are:
how to replace 99999 with some meta symbol to indicate the real line number
I tried sed "50,${/^\s*PUTS/d}" the_file, but it is not right.
how to replace "printf" with an environment variable? I tried
set pattern printf
sed "50,99999{/^\s*$pattern/d}" the_file
but it is not right.
Assuming a Bourne-like shell such as bash:
Simply define shell variables and splice them into your sed command string:
endLine=99999
pattern='printf'
sed '50,'"$endLine"'{ /^\s*'"$pattern"'/d; }' the_file
Note that the static parts of the sed command strings are single-quoted, as that protects them from interpretation by the shell (which means you needn't quote $ and `, for instance).
You can put everything into a single double-quoted string so as to be able to embed variable references directly, but distinguishing between what the shell will interpret up front and what sed will interpret can get confusing quickly.
That said, using a double-quoted string for the case at hand is simple:
sed "50,$endLine { /^\s*$pattern/d; }" the_file
sed "50,${/^\s*PUTS/d}" the_file
this line won't work, because you used double quotes, and you need escape the dollar: \$ or use single quote: '50,${/.../d}' file
sed "50,99999{/^\s*$pattern/d}" file
this line should work.
EDIT
wait, I just noticed that you set env var via set... this is not correct if you were with Bash. you should use export PAT="PUT" in your script.
check #Jonathan and #tripleee 's comments