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
Related
I have a script to replace a specific email address in various files. The replacement address is the first parameter to the script:
#!/bin/bash
perl -pi -e s/'name\#domain\.org'/$1/ file-list
This doesn't work, as the # character in $1 is substituted by perl. Is there a straightforward fix for this? Running the script as subst foo\#bar.com, subst foo\\#bar.com, subst "foo#bar.com", and so on, doesn't work. Is there a sed script that could handle this more easily?
Instead of expanding a shell variable directly in the perl code you can pass it as an argument by setting the s switch:
#!/usr/bin/env bash
perl -i -spe 's/name\#domain\.org/$replacement/' -- -replacement="$1" file1.txt file2.txt
In perl's s///, without the use of e or ee modifiers, variables in the replacement part are treated as literals so you don't need to escape them.
This works, but needs you to pass the new mail address to the script with the # character preceded by \\:
#!/bin/bash
perl -pi -e "s/name\#domain.org/$1/" file-list
If the script is subst, run as:
subst newname\\#example.com
This is a better alternative, which uses sed to carry out the escaping:
#!/bin/bash
ADR="$(echo "$1" | sed -e 's/#/\\\#/')"
perl -pi -e "s/name\#domain.org/$ADR/" file-list
Of course, in this case it's probably better to use sed to do the whole thing.
I have been trying to replace some text in a .txt file using a shell script and perl.
oldKey=123
trimmedNewKey=456
#Export shell variables, so that they can be used by perl
export oldKey
export trimmedNewKey
#Search and Replace
perl -pi -e 's/$ENV{oldKey}/$ENV{trimmedNewKey}/g' AppConstants.txt
This fails, but on the other hand, if I use string directly for the search param, it works:
perl -pi -e 's/123/$ENV{trimmedNewKey}/g' AppConstants.txt.
I am not a shell guy and can't figure out why my "search" param can't be evaluated via a variable. Help !
Try changing your code into
oldKey=123
trimmedNewKey=456
perl -pi -e "s/$oldKey/$trimmedNewKey/g" AppConstants.txt
This should work, because in a string enclosed in single quotes, there is no variable and wildcard expansion, as it is the case in a string enclosed in double quotes.
It is possible perhaps to pass some variables to perl so that the expansion happens inside the perl program, but why to make it complex when you can solve it in an easier way?
I'm trying to hash a password using the crypt hash function in Perl. In a Bash script so far I have:
password='Pa$$word'
hashedPassword="$(perl -e "print crypt('$password', 'salt'), \"\n"")"
I then modify/copy /etc/shadow using sed:
sed -e '/^user1:/s_:[^:]*:_:'"$hashedPassword"':_' /etc/shadow > /tmp/shadow
The method works, except when passing a string containing single quotes. How can I handle a password containing ' single quotes? Running Solaris 10 OS.
Your problem is in bash. Trying to set a shell variable containing a single quote by enclosing it in single quotes will not work. Per the man 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.
Supply the password as a parameter to your one-liner instead of interpolating it directly in the code:
#!/usr/bin/env bash
password='Pa$$word'
hashedPassword=$(perl -e 'print crypt($ARGV[0], "salt"), "\n"' $password)
echo "p='$password', h='$hashedPassword'"
Output:
p='Pa$$word', h='saFQXTeqbkiIQ'
As password contains $ and $ are syntactical in perl it is not easy to pass in hard in script, other options are to pass by arguments or by environment.
# by argument
perl -e '($password, $salt)=#ARGV;print crypt($password, $salt), "\n"' "$password" "$salt"
# by environment variable
password=$password salt=$salt perl -e 'print crypt($ENV{password}, $ENV{salt}), "\n"'
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
I am writing a shell script to replace a variable content which is an integer with another, using perl in a shell script.
#!/bin/sh
InitialFileStep="$1"
CurrentStage=$((($i*(9*4000))+$InitialFileStep))
PreviousStage=$((($(($(($i-1))*(9*4000)))) + (InitialFileStep)))
perl -pi -e 's/$PreviousStage/$CurrentStage/g' file.txt
echo "Hey!"
It seems it cannot find the variable content in the file.
I don't know what is the problem, is it the because the variables are integers and not strings?
The shell does not interpret anything inside single quote. '$ThisIsASimpleStringForTheShell' so try:
perl -pi -e 's/'"$PreviousStage"'/'"$CurrentStage"'/g' file.txt
The double quotes prevents possible spaces to mess up your command.
Mixing single and double quotes gives you the possibility to add regex operator to your command, preventing shell to interpret them before perl. This command substitute the contents of $PreviousStage with the contents of $CurrentStage only if the former is alone in a single line:
perl -pi -e 's/^'"$PreviousStage"'$/'"$CurrentStage"'/g' file.txt
The variables only exist in your shell script; you can't directly use them in your Perl script.
I hate attempting to generate Perl code from the shell as the previous solutions suggest. That way madness lies (though it works here since you're just dealing with integers). Instead, pass the values as arguments or some other way.
perl -i -pe'BEGIN { $S = shift; $R = shift; } s/\Q$S/$R/g' \
"$PreviousStage" "$CurrentStage" file.txt
or
export PreviousStage
export CurrentStage
perl -i -pe's/\Q$ENV{PreviousStage}/$ENV{CurrentStage}/g' file.txt
or
S="$PreviousStage" R="$CurrentStage" perl -i -pe's/\Q$ENV{S}/$ENV{R}/g' file.txt