rename a string in a perl script eg name("this stays the same") - perl

perl -pi-back -e 's/ACTUAL_WORD\(`SOMETHING`\)/EXPECTED_WORD\(`SOMETHING`\)/g;' \
inputfile.txt
I need the "something" to stay the same. something is like a variable that changes.

I think something like this should do it?
perl -pi-back -e 's/ACTUAL_WORD(.*)/EXPECTED_WORD($1)/g;' inputfile.txt
You capture the word in brackets and reuse it via $1 in the replacement. (You may need more brackets - it's unclear if additional are required based on your input).

Related

What is the purpose of filtering a log file using this Perl one-liner before displaying it in the terminal?

I came across this script which was not written by me, but because of an issue I need to know what it does.
What is the purpose of filtering the log file using this Perl one-liner?
cat log.txt | perl -pe 's/\e([^\[\]]|\[.*?[a-zA-Z]|\].*?\a)/ /g'
The log.txt file contains the output of a series of commands. I do not understand what is being filtered here, and why it might be useful.
It looks like the code should remove ANSI escape codes from the input, i.e codes to set colors, window title .... Since some of these code might cause harm it might be a security measure in case some kind of attack was able to include such escape codes into the log file. Since usually a log file does not contain any such escape codes this would also explain why you don't see any effect of this statement for normal log files.
For more information about this kind of attack see A Blast From the Past: Executing Code in Terminal Emulators via Escape Sequences.
BTW, while your question looks bad on the first view it is actually not. But you might try to improve questions by at least formatting it properly. Otherwise you risk that this questions gets down-voted fast.
First, the command line suffers from a useless use of cat. perl is fully capable of reading from a file name on the command line.
So,
$ perl -pe 's/\e([^\[\]]|\[.*?[a-zA-Z]|\].*?\a)/ /g' log.txt
would have done the same thing, but avoided spawning an extra process.
Now, -e is followed by a script for perl to execute. In this case, we have a single global substitution.
\e in a Perl regex pattern corresponds to the escape character, x1b.
The pattern following \e looks like the author wants to match ANSI escape sequences.
The -p option essentially wraps the script specified with -e in while loop, so the s/// is executed for each line of the input.
The pattern probably does the job for this simple purpose, but one might benefit from using Regexp::Common::ANSIescape as in:
$ perl -MRegexp::Common::ANSIescape=ANSIescape,no_defaults -pe 's/$RE{ANSIescape}/ /g' log.txt
Of course, if one uses a script like this very often, one might want to either use an alias, or even write a very short script that does this, as in:
#!/usr/bin/env perl
use strict;
use Regexp::Common 'ANSIescape', 'no_defaults';
while (<>) {
s/$RE{ANSIescape}/ /g;
print;
}

why is my perl command line replace not working?

I'm running this but it doesn't seem to replace anything:
perl -p -i -e 's/page?user_id=/page?uid=/g' *
What am I doing wrong here?
I want to replace page?user_id= with page?uid=
The '?' is a special character, indicating that the e needs to be matched 0 or once, so it needs to be escaped if you want to search for a '?' instead of an optional 'e'. Escaping with '\':
try
s/page\?user_id=/page?uid=/g
You can also use Quotemeta:
perl -pi -e 's/\Qpage?user_id=\E/page?uid=/g' file
As a side note I thought why don't you change only user_id to uid.

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

sed in perl script

I am using following kind of script in my perl script and expecting entry at line 1. I am getting some error as below; any help?
plz ignore perl variable....
Error Messaage -
sed: -e expression #1, char 22: extra characters after command
# Empty file will not work for Sed line number 1
`"Security Concerns Report" > $outputFile`;
`sed '1i\
\
DATE :- $CDate \
Utility accounts with super access:- $LNumOfSupUserUtil \
Users not found in LDAP with super access: - $LNumOfSupUserNonLdap\
' $outputFile > $$`;
`mv $$ $outputFile`;
}
Your immediate problem is that the backslash character is interpreted by Perl inside the backtick operator, as is the dollar character. So your backslash-newline sequence turns into a newline in the shell command that is executed. If you replace these backslashes by \\, you'll go over this hurdle, but you'll still have a very brittle program.
Perl is calling a shell which calls sed. This requires an extra level of quoting for the shell which you are not performing. If your file names and data contain no special characters, you may be able to get away with this, until someone uses a date format containing a ' (among many things that would break your code).
Rather than fix this, it is a lot simpler to do everything in Perl. Everything sed and shells can do, Perl can do almost as easily or easier. It's not very clear from your question what you're trying to do. I'll focus on the sed call, but this may not be the best way to write your program.
If you really need to prepend some text to an existing file, there's a widely-used module on CPAN that already does this well. Use existing libraries in preference to reinventing the wheel. File::Slurp has a prepend_file method just for that. In the code below I use a here-document operator for the multiline string.
use File::Slurp; # at the top of the script with the other use directives
File::Slurp->prepend_file($outputFile, <<EOF);
DATE :- $CDate
Utility accounts with super access:- $LNumOfSupUserUtil
Users not found in LDAP with super access: - $LNumOfSupUserNonLdap
EOF

Replacing a part of a line with bash / perl

I'm a noob at bash need to replace the mypassword part of this line in a file
"rpc-password": mypassword
with mynewpassword
I tried
perl -pi -e "s,PASSWORD,${password},g" "${user_conf}"
but it dosen't seem to do anything :(
I can use anything that will work inside a bash script, it dosen't have to be bash or perl.
perl -pi -e 's/mypassword/mynewpassword/g' file
will work
Using a loose regex without keeping backups is a bad idea. Especially if you intend to use dynamic replacement strings. While it may work just fine for something like "mypassword", it will break if someone tries to replace with the password "ass" with "butt":
"rpc-password": mypassword
Would become:
"rpc-pbuttword": butt
The more automation you seek, the more strict you need the regex to be, IMO.
I would anchor the replacement part to the particular configuration line that you seek:
s/^\s*"rpc-password":\s*\K\Q$mypassword\E\s*$/$mynewpassword/
No /g modifier, unless you intend to replace a password several times on the same line. \K will preserve the characters before it. Using \s* liberally will be a safeguard against user-edited configuration files where extra whitespace might have been added.
Also, importantly, you need to quote meta characters in the password. Otherwise a password such as t(foo)? Will also match a single t. In general, it will cause strange mismatches. This is why I added \Q...\E (see perldoc perlre) to the regex, which will allow variable interpolation, but escape meta characters.
You can also use sed for this:
sed -i 's/mypassword/mynewpassword/g' file