#!/usr/bin/perl # snip -- perl: snips a pattern from input lines. Or replaces a pattern. # # # Author: Eric Canzler Create Date: 06/14/2017 # # Total rewrite to simplify the code. Change Date: 08/26/2017 # Added comments and help Change Date: 06/14/2017 # Review: Eric canzler Review Date: 08/30/2017 # # Deletes or replaces a pattern in a line opf text. snip only deletes # or replaces the first instance of a match by default. snip read STDIN # only not files, so you have to pip input through it. snip with no # CLI arguments prints usage. # Basically, if we get one CLI argument, the that is the thing to delete. # If we get two CLI arguments, then the second one is a pattern to replace the # delete pattern with. If there are three CLI arguments, then the third one # is a modifier, g = global, i = ignore case. The modifier must be lowercase, # and cat take four values, i, g, ig, gi. Thats it. Since the modifier must # be the third CLI argument, you have to provide a replace string, in order # to have three arguments. If you want to delete only and NOT replace, the # provid the empty string as the second CLI argument. It will replace the # delete string with nothing which is the same as simply deleting. In fact, # thats what it does by default anyway with only a single CLI argument. $argcount = scalar(@ARGV); if (($ARGV[0] =~ /^-h/i) || ($ARGV[1] =~ /^-h/i) || ($ARGV[2] =~ /^-h/i) || ($argcount < 1)) { print <<'EOF'; Usage: snip deletestring [replacestring] [gi] snip - prints integers from start to stop, incrementing by step. You must pipe input through STDIN to snip. snip does not read files. Usage: snip delete-string optional-replace-string optional-modifier The optional modifier can be i, g, ig, or gi. i = case insensitive, g = global The modifier must be the third CLI argument. In order to delete without replacing, but also use g or i modifier, you have to give an empty replace-string using double quotes. Replacing with nothing is equivilent to delete. Examples: (assume cat filename | snip command below) snip OLD "" i # delete the first instance of "OLD" ignoring case snip OLD NEW # replace the first instance of "OLD" with "NEW" snip OLD "" gi # delete instances of "OLD" globally ignoring case snip OLD New gi # replace any case version of "OLD" with "New" globally snip OLD # delete the first instance of "OLD" only snip OLD New # replace the first instance of "OLD" with "New" You can't specify a specific instance to delete or replace. It's either the first only, or ALL intances. But you can replace with temporary values and then replace them with what you need. EOF exit(0); } $replace = ""; if ($argcount > 1) { $both = 1; $delete = $ARGV[0]; $replace = $ARGV[1]; } else { $delete = $ARGV[0]; } $modify = "no"; if (defined($ARGV[2])) { $modify = $ARGV[2]; } # Silently escape backtics. This is to prevent executing a system command. $delete =~ s/`/\`/g; $replace =~ s/`/\`/g; while ($line = ) { if ($modify eq "g") { $line =~ s/$delete/$replace/g; } if ($modify eq "i") { $line =~ s/$delete/$replace/i; } if ($modify eq "gi") { $line =~ s/$delete/$replace/gi; } if ($modify eq "ig") { $line =~ s/$delete/$replace/ig; } if ($modify eq "no") { $line =~ s/$delete/$replace/; } # There are no other valid modify values, so if $modify didn't match one # of the above, then nothing was done to the line. So it just ends up # catting the file to STDOUT. In any case print out whatever it turns out # to be. print $line; }