From: Nicolas Boisselier Date: Sat, 10 Dec 2022 17:03:08 +0000 (+0100) Subject: bin/shell-replace X-Git-Url: https://git.nbdom.net/?a=commitdiff_plain;h=54ac9dc233cb67ca5219ea0c8187c9e54b4e1b47;p=nb.git bin/shell-replace --- diff --git a/bin/shell-replace b/bin/shell-replace new file mode 100755 index 00000000..c2a76a69 --- /dev/null +++ b/bin/shell-replace @@ -0,0 +1,313 @@ +#!/usr/bin/perl +use strict; +use warnings; +################################################################################# +# +# VERSION +# +################################################################################# +my $VERSION = '0.0.1'; +# NB 10.12.22 +# - create script + +################################################################################# +# +# GLOBALS +# +################################################################################# +my ($NAME) = $0 =~ m,([^/]+)$,; + +# To ignore myself +my $SHELL_IGNORE = '^my \$SHELL_IGNORE'; + +################################################################################# +# +# ARGS +# +################################################################################# +my $VERBOSE = $main::VERBOSE = 1; +my $DEBUG = $main::DEBUG = 0; + +my %Opt = ( +); +get_options(\%Opt); +#help() unless @ARGV; +$main::_DATA_ = undef; + +################################################################################# +# +# BEGIN +# +################################################################################# +use Data::Dumper; +use File::Find; +if (!@ARGV and !-t STDIN) { + die "$NAME: option require file/path as arguments!\n" if $Opt{find}; + @ARGV = "-"; +} + + +# +# Option --find +# +my @WANTED_FILES = (); +if ($Opt{find}) { + File::Find::find({ + wanted => \&wanted, + follow => 1, + follow_skip => 2, + no_chdir => 1 + }, @ARGV); + #exit; + #die Dumper(\@WANTED_FILES); + @ARGV = @WANTED_FILES; +} + +# +# Process +# +my $hfile; +my $file; + +for $file (@ARGV) { + + if ($file eq "-") { + $hfile = <>; + $hfile = \*ARGV; + } else { + next if myself($file); + open($hfile,"<",$file); + } + + verbose(1,">Processing: $file\n"); + + my @lines = &shell_replace($hfile); + print map { $_ } @lines; + close $hfile; +} + +################################################################################# +# +# END +# +################################################################################# +exit 0; + +################################################################################# +# +# Functions +# +################################################################################# +sub verbose { + my $level = shift @_; + return 0 if $VERBOSE <= $level; + print STDERR join(" ",@_)."\n"; +} +sub myself { + my $file = shift @_; + if ($file eq $0 or $file =~ /(^|\/)$NAME$/) { + verbose(1,"ignore file $file\n"); + return 1 + } + return 0; +} + +sub wanted { + my $file = $File::Find::name; + + # Dont want the myself + return if myself($file); + + my $hfile; + open($hfile,"<","$file"); + while (<$hfile>) { + # Dont want the myself + next if /$SHELL_IGNORE/; + + next unless /^.{1,3}Found: $file\n"); + push @WANTED_FILES, $file; + last; + } + close $hfile; +} + +sub shell_replace { +my $ident; +my $i; +my $change; +my $cmd; +my @lines = (); + +my $hfile = shift @_; + while (my $line = <$hfile>) { + + if ( + $line =~ /^(\s*).{1,3}>SHELL_REPLACE (.*)$/ + .. + $line =~ /^\s*.{1,3}>".$line; next; + $i++; + if ($2) { + $cmd = "bash -lc \"$2\""; + if ($i==1) { push @lines, $line; push @lines, map{s/^/$ident/;$_} `$cmd`; } + elsif (/^\s*.{1,3}; + push @lines, $line; + push @lines, map{ s/^/$ident/; $_ } `$cmd`; + $change = 1; + + } else { + $i=0; + push @lines, $line; + + } + + } + return @lines; +} + +sub help { +#------------------------------------------------------------------------------ +# Print help and exit +#------------------------------------------------------------------------------ + + require 'Pod/Usage.pm' unless $INC{'Pod/Usage.pm'}; + + # Substitutions + sub pod_env { + my $v = ''; + eval '$v = ref(\\'.$_[0].') eq "ARRAY" ? join(" ",'.$_[0].') : '.$_[0].'; return defined $v ? $v : qq|UNDEF|;'; + return $v; + } + + $main::_DATA_ =~ s/([@\$][A-Z_a-z\{\}]+)/pod_env($1)/eg; + + my $in; + open($in,'<',\$main::_DATA_); + + open(STDOUT,"|perl -pe 's/\.$$//g'".(($ENV{PAGER}||'') eq 'less' ? "|less -FRi" : "")); + my $opts = { + -input => $in, + -ouput => \*STDOUT, + -exitval => 'noexit', + -sections => [qw(SYNOPSIS DESCRIPTION OPTIONS)], + -verbose => ($Opt{'help'} ? 99 : 3), + }; + + Pod::Usage::pod2usage($opts); + close $in; + close STDOUT; + + exit 0; +} + +#------------------------------------------------------------------------------ +# Print version and exit +#------------------------------------------------------------------------------ +sub version { print "$NAME: version [$VERSION]\n"; exit 0; } + +#------------------------------------------------------------------------------ +# Get options from pod +#------------------------------------------------------------------------------ +sub get_options { + + use Getopt::Long qw(:config no_ignore_case no_auto_abbrev); + + my @Opt; + + sub pod_opt { + local $_; + my $o = shift; + $o =~ s/(=.|[\+\-\!]$)//; + $o = join(", ",map{"-$_"} split(/[\|,:;]/,$o)); + return "$o"; + } + + while () { + s/option\[([^\]]+)\]/push(@Opt,$1) and pod_opt($1)/eg; + $main::_DATA_ .= $_; + } + + GetOptions($_[0],@Opt) || exit -1; + + help() if $_[0]{'help'} or $_[0]{'man'}; + version() if $_[0]{'version'}; + + $main::VERBOSE = $VERBOSE = $_[0]{'verbose'} if defined $_[0]{'verbose'}; + $main::DEBUG = $DEBUG = $_[0]{'debug'} if defined $_[0]{'debug'}; + +} + +__DATA__ + +=head1 NAME + +$NAME - Script replace tags with command in text files + +=head1 SYNOPSIS + +$NAME path/file.txt +$NAME --find path/ + +=over + +=item $NAME --verbose + +=item $NAME --help + +=back + +=head1 DESCRIPTION + +Find files which contains start and tags >SHELL_REPLACE .. SHELL_REPLACE dbq.php nb meta ls key,val cat=mime.comment format=vim_hash preff=$'\t' name=mimeComment +..... +#. + +=head1 SEE ALSO + +perl(1), http://perldoc.perl.org/perlpodstyle.html + +=head1 AUTHOR + +Nicolas Boisselier + +=cut