Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to ask for confirmation using the command `sed` [closed]

Tags:

linux

sed

I'm trying to replace a string over multiple files using the command sed like:

grep -rl matchstring somedir/ | xargs sed -i 's/string1/string2/g'

My question is: is there a way to enable it to ask for confirmation at each substitution?

I tried to include the latter c after g in the substitution command, but it didn't succeed.

Thank you in advance for any comments.

like image 416
lucascavalcante Avatar asked Oct 29 '25 19:10

lucascavalcante


1 Answers

The sed utility does not have confirmation ability. If/Until it is implemented, consider using other tools.

The 'ex' (vim in command line mode), has lot of power, including per change confirmation. The confirmation mode is geared toward visual usage. One problem is that once a single change is not approved, the substitution stop. On the surface, this is not what is being asked.

Potentially solution will be to use scripting engine capable of substitutions, and implement a confirmation logic. Awk, Perl, python meet those requirements.

Perl has edit in place option. Script can be invoked with 'perl -i.bak'.

Security: Notice code may need additional protection against injection into RE. See below

Activate:

grep -rl matchstring somedir/ | xargs perl -i.bak sub-conf.pl 'string1' 'string2'

#! /usr/bin/perl

use strict ;
my ($in_pattern, $replacement) = (shift, shift) ;

  # Convert string to regexp, disable special characters, etc.
my $pattern = quotemeta($in_pattern) ;
open TTY, "/dev/tty" or die "Failed to open TTY: $!" ;
   # Read a line into orig
my $eof ;
while ( my $orig = <> ) {
   my $new = $orig =~ s/$pattern/$replacement/gr ;
   if ( $new ne $orig ) {
       print STDERR "Replace line ${.}:\n< ${orig}> $new" ;
       while (1) {
           print STDERR "(Y/N) ?" ;
           my $yn = <TTY> ;
           unless ( defined($yn) ) { $eof = 1 ; last } ;
           if ( $yn =~ /[Yy]/ ) { print $new ; last ; } ;
           if ( $yn =~ /[Nn]/ ) { print $orig ; last ; } ;
       } ;
   } else {
     print $orig ;
   } ;
   die 'EOF' if $eof ;
} ;

See: How can I safely validate an untrusted regex in Perl? for explanation of the injection protection in case command need to be extended to accept REGEX.

like image 156
dash-o Avatar answered Oct 31 '25 10:10

dash-o



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!