I created the following Perl one-liner in order to remove a word from a file
This Perl also escapes special characters such as @
or $
or *
, so every word that contains a special character will removed from the file.
How to change the Perl syntax in order to delete only the last matched word from a file and not all the words?
Example
more file Kuku Toto Kuku kuku
export REPLACE_NAME="Kuku" export REPLACE_WITH="" perl -i -pe 'next if /^#/; s/(^|s)Q$ENV{REPLACE_NAME }E(s|$)/$1$ENV{ REPLACE_WITH }$2/' file
expected results
more file Kuku Toto Kuku
another example
when – export REPLACE_NAME=”mark@$!”
more file mark@$! hgst#@ hhfdd@@
expected results
hgst#@ hhfdd@@
Advertisement
Answer
Use Tie::File to make this easier.
$ perl -MTie::File -E'tie @file, "Tie::File", shift or die $!; $file[-1] =~ s/bQ$ENV{REPLACE_NAME}Eb/$ENV{REPLACE_WITH}/' file
Update: Rewriting as a program in order to explain it.
# Load the Tie::File module use Tie::File; # Tie::File allows you to create a link between an array and a file, # so that any changes you make to the array are reflected in file. # The "tie()" function connects the file (passed as an argument and # therefore accessible using shift()) to a new array (called @file). tie my @file, 'Tie::File', shift or die $!; # The last line of the file will be in $file[-1]. # We use s/.../.../ to make a substitution on that line. $file[-1] =~ s/bQ$ENV{REPLACE_NAME}Eb/$ENV{REPLACE_WITH}/;
Update: So now you’ve changed you requirements spec. You want to remove the last occurrence of the string, which is not necessarily on the last line of the file.
Honestly, I think you’ve moved past the kind of task that I’d write in command-line switches. It’d write a separate program that looks something like this:
#!/usr/bin/perl use strict; use warnings; use Tie::File; tie my @file, 'Tie::File', shift or die $!; foreach (reverse @file) { if (s/bQ$ENV{REPLACE_NAME}Eb/$ENV{REPLACE_WITH}/) { last; } }