How to use a shell variable inside sed when doing "d" command? - bash

In my bash, I wish to delete lines from 1 to ${number}, like this:
number=10
sed '1,${number}d' myfile
It failed with syntax error.
I also tried "\${number}", '"$number"', neithers works
I changed to double quote, it works under command line, but not inside bash script file. How to make it work?

Enclose your sed expression in double quotes to interpolate the variable number:
sed "1,${number}d" file

Please use double quotes instead of single quotes while running sed this way.
Read here for Difference between single and double quotes

I changed to double quote, it works under command line, but not inside
bash script file
Assuming your bash script is:
sed "1,${number}d" myfile
you should export number variable in bash prompt so that it can be visible in bash script when it is run:
export number=10

Related

How do I escape a single quote inside single quotes in jenkins-pipeline bash command

in jenkins-pipeline, I'm trying to use SED to append the following line to the end of a file.
sh "sed -i '\$ s/\$/ public_file=\\/var\\/lib\\/jenkins\\/workspace\\/test-project\\ ansible_ssh_common_args='-o StrictHostKeyChecking=no' /' file.txt"
but I can't figure out how to escape the below line in my Jenkins file to make it work.
ansible_ssh_common_args='-o StrictHostKeyChecking=no'
I've already tried the following, which works in katacoda playground, but not in jenkins pipeline.
'"'"'-o StrictHostKeyChecking=no'"'"' /' file.txt
use " to wrap sed command, then you can use ' in command directly without to escape it.
use #, but / as delimiter for sed s command, then you no need to escape the / appeared in file path to make the whole commend more concise and readable.
sed -i "\$ s#\$# public_file=/var/lib/jenkins/workspace/test-project ansible_ssh_common_args='-o StrictHostKeyChecking=no' #" file.txt
In bash, you cannot escape single quotes within single quotes.
See the bash manual page:
Enclosing characters in single quotes preserves the literal value of each character within the quotes. A single quote may not occur between single quotes, even when preceded by a backslash.
You can use double quotes instead; then escape them as needed. You can then use single quotes within them without further escaping.

Replace Double quotes with space

this is perhaps one of the most discussed topics here. I tried almost all the commands and other tweaks found here, but something doesn't seems to be doing well.
i would want to replace all the double quotes in my file with whitespace/blank
I'm seeing the below error when i tried to execute this command.
sed "s/"/ \''/g' x_orbit.txt > new.tx
sed: -e expression #1, char 3: unterminated `s' command
You're close. Just use single quotes, so the shell doesn't try to expand the metacharacters in your sed command:
sed 's/"/ /g' x_orbit.txt > new.txt
You could try tr for example:
tr '"' ' ' < x_orbit.txt > new.txt
The script you provided:
sed "s/"/ \''/g' x_orbit.txt > new.tx
means:
sed # invoke sed to execute the following script:
" # enclose the script in double quotes rather than single so the shell can
# interpret it (e.g. to expand variables like $HOME) before sed gets to
# interpret the result of that expansion
s/ # replace what follows until the next /
" # exit the double quotes so the shell can now not only expand variables
# but can now do globbing and file name expansion on wildcards like foo*
/ # end the definition of the regexp you want to replace so it is null since
# after the shell expansion there was no text for sed to read between
# this / and the previous one (the 2 regexp delimiters)
\' # provide a blank then an escaped single quote for the shell to interpret for some reason
'/g' # enclose the /g in single quotes as all scripts should be quoted by default.
That is so far off the correct syntax it's kinda shocking which is why I dissected it above to try to help you understand what you wrote so you'll see why it doesn't work. Where did you get the idea to write it that way (or to put it another way - what did you think each character in that script meant? I'm asking as it indicates a fundamental misunderstanding of how quoting and escaping works in shell so it'd be good if we could help correct that misunderstanding rather than just correct that script.
When you use any script or string in shell, simply always enclose it in single quotes:
sed 'script' file
var='string'
unless you NEED to use double quotes to let a variable expand and then use double quotes unless you NEED to use no quotes to let globbing and file name expansion happen.
An awk version:
awk '{gsub(/"/," ")}1' file
gsub is used for the replace
1 is always true, so line is printed

proper syntax for the s command along to the addressing in sed

I want to issue this command from the bash script
sed -e $beginning,$s/pattern/$variable/ file
but any possible combination of quotes gives me an error, only one that works:
sed -e "$beginning,$"'s/pattern/$variable/' file
also not good, because it do not dereferences the variable.
Does my approach can be implemented with sed?
Feel free to switch the quotes up. The shell can keep things straight.
sed -e "$beginning"',$s/pattern/'"$variable"'/' file
You can try this:
$ sed -e "$beginning,$ s/pattern/$variable/" file
Example
file.txt:
one
two
three
Try:
$ beginning=1
$ variable=ONE
$ sed -e "$beginning,$ s/one/$variable/" file.txt
Output:
ONE
two
three
There are two types of quotes:
Single quotes preserve their contents (> is the prompt):
> var=blah
> echo '$var'
$var
Double quotes allow for parameter expansion:
> var=blah
> echo "$var"
blah
And two types of $ sign:
One to tell the shell that what follows is the name of a parameter to be expanded
One that stands for "last line" in sed.
You have to combine these so
The shell doesn't think sed's $ has anything to do with a parameter
The shell parameters still get expanded (can't be within single quotes)
The whole sed command is quoted.
One possibility would be
sed "$beginning,\$s/pattern/$variable/" file
The whole command is in double quotes, i.e., parameters get expanded ($beginning and $variable). To make sure the shell doesn't try to expand $s, which doesn't exist, the "end of line" $ is escaped so the shell doesn't try anything funny.
Other options are
Double quoting everything but adding a space between $ and s (see Ren's answer)
Mixing quoting types as needed (see Ignacio's answer)
Methods that don't work
sed '$beginning,$s/pattern/$variable/' file
Everything in single quotes: the shell parameters are not expanded (doesn't follow rule 2 above). $beginning is not a valid address, and pattern would be literally replaced by $variable.
sed "$beginning,$s/pattern/$variable/" file
Everything in double qoutes: the parameters are expanded, including $s, which isn't supposed to (doesn't follow rule 1 above).
the following form worked for me from within script
sed $beg,$ -e s/pattern/$variable/ file
the same form will also work if executed from the shell

Shell Scripting How to combine variables and wildcard

I have a simple shell script to run several commands at once. I can't figure out how to do this:
'mkdir -p $FULL_BACKUP_PATH; cp -r $FULL_PATH/* $FULL_BACKUP_PATH/.;'
If I use single quotes, the variables don't get the values, if I use double quotes, the wildcard does not expand.
Please help
Thanks
I think you want this:
mkdir -p "${FULL_BACKUP_PATH}"; cp -r "${FULL_PATH}/*" "${FULL_BACKUP_PATH}"
Variables inside double quotes get expanded, variables inside single quotes do not. Always put variables inside double quotes if they are paths/directories in case they have spaces in them so the double quotes "hold them together".
If the code appears in shell script that starts with a shebang like this:
#!/bin/bash
you can temporarily add -xv after bash to see the script expanded as it is executed and that will help you debug it, like this:
#!/bin/bash -xv

insert bash variable into perl search and replace

in my bash script i look for text inside a file and replace it with a variable from my bash script. I couldn't get the variable to be recognized by the perl command. any ideas?
mybash.bash:
#! /bin/sh
let "myNum=2"# myNum could be any integer
perl -pi -e 's/ABCD\d/ABCD$myNum/g' ./textfile.txt
textfile.txt:
'ABCD0' gets replace with 'ABCD' with above script
Use double quotes so as to enable interpolation of variables:
perl -pi -e "s/ABCD\d/ABCD$myNum/g" ./textfile.txt
^^^ ^^^
Have you tried using $($myNum) ? Bash needs to be able to execute/evaluate the variable?
Also, single quotes print literal fields usually and double evaluate things, so you might need to fiddle with that if the above doesn't work

Resources