Replacing terms in multiple files using Perl - sh

I would like to replace some values in input files named " i_f.xyz " using perl, where i goes from 1 to 19.
In my files, I want to change a "6" into a "C".
To do so I tried
perl -pi -e 's/6/C/g' ${i}_f.xyz
, and some other combinations but it doesn't work.
Anyone can help me please ? Thanks a lot :)

You need to iterate over the placeholder variable. Use for.
#!/bin/bash
for ((i=1; i<=19; i++)); do
perl -pi -e 's/6/C/g' "${i}_f.xyz"
done
Edit: replace seq with bash built-in

Even simpler (no need any loop):
perl -i -pe 's/6/C/g' 1[0-9]_f.xyz [0-9]_f.xyz
(from 1_f.xyz to 19_f.xyz)

Thanks a lot for your answer guys.
At the end I found a solution to do it with:
#! /bin/bash
for i in *_f.xyz
do
perl -pi -e 's/6/C/g' *_f.xyz
perl -pi -e 's/1/H/g' *_f.xyz
done
But now I've got other approachs also ! I'm new in bash script, programming language and other computer science things, so thanks ! :)

Related

Replacing everything between two strings in UNIX shell

I want to write a shell script that gets all "a href" HTML tags from provided link and prints them to the console. The problem I am facing right now is removing all of the text I don't need between them. After some googling I came to a conclusion, that the "sed" command would be the best for this job, however, I cannot figure out how to write it correctly
#!/bin/sh
wget -qO - $1 | grep -E "*<[Aa]([[:print:]])*( |'\n')[Hh][Rr][Ee][Ff]([[:print:]])*</a" | sed 's/<\/a>.*<a/<\/a>REPLACED\n<a/g'
What I am trying to do is to replace EVERYTHING between the "</a>" closing tag and the next "<a" opening tag (I don't know much about HTML, but there may be other tags that have "a" as opening and closing, but that's a problem for later), however, this (and a few different ways I have tried) only works sometimes.
I am new to shell scripting, so any suggestions are welcome, maybe "sed" is not the command for the job, hope you can help me, thanks in advance
Edit 1: from this:
Canonical</li></ul></li></ul></div></div> <script> $(function() { $(".nav-global .more > a").click(function(e){ $(this).closest(".more").toggleClass("open"); return false; }); $(document).click(function(){ $(".nav-global .more.open").removeClass("open"); }); }); </script></div>
<span></span>
to this:
CanonicalREPLACED<span></span>
Edit 2:
It seems I am bad at explaining exactly what I expect. For large-scale testing, I use the link https://askubuntu.com/questions/726076/whats-wrong-with-my-grep-command. What I am trying to achieve is to have ONLY "a href" (or other HTML tags that start with "<a" and end with "</a>") separated by "REPLACED" as shown in previous edit
1st solution: With your shown samples please try following awk code. Written and tested in GNU awk.
awk -v RS="" -v FS='<\\/a>.*<a href=' '{print $1"</a>REPLACED<a href="$2}' Input_file
2nd solution: Using RS and sub functions of awk, written and tested in GNU awk.
awk -v RS="" '{sub(/<\/a>.*<a href=/,"</a>REPLACED<a href=")} 1' Input_file
Using sed
$ sed -Ez 's~(<[^<]*)[^\n]*\n +~\1</a>REPLACED~' input_file
CanonicalREPLACED<span></span>
Output result to stdout:
sed -z 's/\(<\/a>\).*\(<a\)/\1REPLACED\2/g' inputfile

Perl Search and Replace Command Not Working When Called from Inside another Perl Script

I am a beginner with Perl. I am using the Below Perl Command To Search and Replace "/$" Sequence in my tcl Script. This works well When used on the linux Command Line directly.
perl -p -i -e 's/\/\$/\/\\\$/g' sed_list.tcl
I am calling to Call the above Perl One liner in another Perl script using System Command and only with " ` " Back Tick.
system(`perl -p -i -e 's/\/\$/\/\\\$/g' sed_list.tcl`);
`perl -p -i -e 's/\/\$/\/\\\$/g' sed_list.tcl`;
I am getting the Below error. Please Help With this issue.
Bareword found where operator expected at -e line 1, near "$/g"
(Missing operator before g?)
Final $ should be \$ or $name at -e line 1, within string
syntax error at -e line 1, near "s//$/"
Execution of -e aborted due to compilation errors.
I Dont Know if I Can use any other Separation Operator like % and # just like SED command but, When I used '%' operator for separation, I didn't see error but job is not done.
`perl -p -i -e 's%\/\$%\/\\\$%g' sed_list.tcl`;
I couldn't find sufficient results for this particular issue of '$' variable on the web. Any help is appreciated.
Some one here Suggested that I should Escape all Back Slashes while using System Command or calling another command using BackTicks from inside a perl script. But later they have deleted their answer. It worked for me. I would like to thank every one for taking effort and helping me out in solving my question.
Here is the correct working code.
`perl -p -i -e 's/\\\/\\\$/\\\/\\\\\\\$/g' sed_list_gen.tcl`;
or Use System function as shown Below
system("perl -p -i -e 's/\\\/\\\$/\\\/\\\\\\\$/g' sed_list_gen.tcl");
Thanks once again for the community for helping me out. . .
You can execute an external command by passing the command to a system function or by using backticks(``) operator. Please pass the command to the system() function as a string:
system(q{perl -p -i -e 's/\/\$/\/\\\$/g' sed_list.tcl})
or use backticks as:
`perl -p -i -e 's/\/\$/\/\\\$/g' sed_list_gen.tcl`
Edit:
As suggested by Paul in the comments.

grep regex to perl or awk

I have been using Linux env and recently migrated to solaris. Unfortunately one of my bash scripts requires the use of grep with the P switch [ pcre support ] .As Solaris doesnt support the pcre option for grep , I am obliged to find another solution to the problem.And pcregrep seems to have an obvious loop bug and sed -r option is unsupported !
I hope that using perl or nawk will solve the problem on solaris.
I have not yet used perl in my script and am unware neither of its syntax nor the flags.
Since it is pcre , I beleive that a perl scripter can help me out in a matter of minutes. They should match over multiple lines .
Which one would be a better solution in terms of efficiency the awk or the perl solution ?
Thanks for the replies .
These are some grep to perl conversions you might need:
grep -P PATTERN FILE(s) ---> perl -nle 'print if m/PATTERN/' FILE(s)
grep -Po PATTERN FILE(s) ---> perl -nle 'print "$1\n" while m/(PATTERN)/g' FILE(s)
That's my guess as to what you're looking for, if grep -P is out of the question.
Here's a shorty:
grep -P /regex/ ====> perl -ne 'print if /regex/;'
The -n takes each line of the file as input. Each line is put into a special perl variable called $_ as Perl loops through the whole file.
The -e says the Perl program is on the command line instead of passing it a file.
The Perl print command automatically prints out whatever is in $_ if you don't specify for it to print out anything else.
The if /regex/ matches the regular expression against whatever line of your file is in the $_ variable.

Perl command is not behaving as expected?

I have a file with below contents:
[TEMP.s_m_update_BUS_spec]
$$SRC_STAT_RA=WHG_STATUS_SITEENTSEQCHAIN_20110901094550.dat
$InputFile_RA_SPE=/edwload/rqt/workingdir/status_spe/WHG_STATUS_SITEENTSEQCHAIN_20110901094550.dat
[TEMP.s_m_upd_salions_rqthk]
$$SRC_STAT_RN=WHG_STATUS_SITEENTSEQCHAIN_20110901094550
$InputFile_RN_RQT=/edwload/rqt/workingdir/restriction/WHG_STATUS_SITEENTSEQCHAIN_20110901094550.dat
I am using below perl command to just replace WHG_STATUS_SITEENTSEQCHAIN_20110901094550 with WHG_STATUS_SITEENTSEQCHAIN_20110901999999.dat in the section [TEMP.s_m_upd_salions_rqthk] But somehow its not giving me expected result. Even the WHG_STATUS_SITEENTSEQCHAIN_20110901094550 under section [TEMP.s_m_update_BUS_spec] is getting replaced.
perl -p -i -e "s|\$\$SRC_STAT_RN=.*|\$\$SRC_STAT_RN=WHG_STATUS_SITEENTSEQCHAIN_20110901999999.dat|g;s|\$InputFile_RN_RQT=\/edwload\/rqt\/workingdir\/restriction\/.*|\$InputFile_RN_RQT=\/edwload\/rqt\/workingdir\/restriction\/WHG_STATUS_SITEENTSEQCHAIN_20110901999999.dat|g" Input_File
Please let me know the modifications required in command above.Same subsitute commands works fine with SED command. But i wud want to use perl.
The program you run is
s|$$SRC_STAT_RN=.*|$$SRC_STAT_RN=WHG_STATUS_SITEENTSEQCHAIN_20110901999999.dat|g; s|$InputFile_RN_RQT=\/edwload\/rqt\/workingdir\/restriction\/.*|$InputFile_RN_RQT=\/edwload\/rqt\/workingdir\/restriction\/WHG_STATUS_SITEENTSEQCHAIN_20110901999999.dat|g
There are a fair number of $ that should be escaped but aren't. It would be simpler if you used single quotes instead of double quotes. You were probably trying for:
perl -i -pe'
s{\$\$SRC_STAT_RN=.*}{\$\$SRC_STAT_RN=WHG_STATUS_SITEENTSEQCHAIN_20110901999999.dat}g;
s{\$InputFile_RN_RQT=/edwload/rqt/workingdir/restriction/.*}{\$InputFile_RN_RQT=/edwload/rqt/workingdir/restriction/WHG_STATUS_SITEENTSEQCHAIN_20110901999999.dat}g;
' Input_File
What exactly is not working as you want? On my machine, after running your perl code, the file looks like:
[TEMP.s_m_update_BUS_spec] $$SRC_STAT_RA=WHG_STATUS_SITEENTSEQCHAIN_20110901999999.dat
[TEMP.s_m_upd_salions_rqthk] $$SRC_STAT_RN=WHG_STATUS_SITEENTSEQCHAIN_20110901999999.dat
Ain't this what you expected?
Edit
Try modifying your command to:
perl -p -i -e "s|\$\$SRC_STAT_RN=.*?|\$\$SRC_STAT_RN=WHG_STATUS_SITEENTSEQCHAIN_20110901999999.dat|gmx;s|\$InputFile_RN_RQT=/edwload/rqt/workingdir/restriction/.*?|\$InputFile_RN_RQT=/edwload/rqt/workingdir/restriction/WHG_STATUS_SITEENTSEQCHAIN_20110901999999.dat|gmx" Input_File
and see if the result is as expected:
[TEMP.s_m_update_BUS_spec]
$$SRC_STAT_RA=WHG_STATUS_SITEENTSEQCHAIN_20110901999999.datWHG_STATUS_SITEENTSEQCHAIN_20110901094550.dat
$InputFile_RA_SPE=WHG_STATUS_SITEENTSEQCHAIN_20110901999999.dat/edwload/rqt/workingdir/status_spe/WHG_STATUS_SITEENTSEQCHAIN_20110901094550.dat
[TEMP.s_m_upd_salions_rqthk]
$$SRC_STAT_RN=WHG_STATUS_SITEENTSEQCHAIN_20110901999999.datWHG_STATUS_SITEENTSEQCHAIN_20110901094550
$InputFile_RN_RQT=WHG_STATUS_SITEENTSEQCHAIN_20110901999999.dat/edwload/rqt/workingdir/restriction/WHG_STATUS_SITEENTSEQCHAIN_20110901094550.dat

Perl: Loop through a file and substitute

I simply wanna read in a logfile, do a search and replace, and then write out the changes to that same logfile.
What's the best practice way of doing this in Perl?
I normally code up a one liner for this:
perl -i -pe 's/some/thing/' log.file
See Here
This is often done with a one-liner:
perl -pi.bak -e "s/find/replace/g" <file>
Note the -i.bak portion -- this creates a backup file with the extension .bak. If you want to play without a net you can do this to overwrite the existing file without a backup:
perl -pi -e "s/find/replace/g" <file>
or you can use sed (I know... you asked about perl):
sed -i 's/find/replace/g' <file>