summary refs log tree commit diff
diff options
context:
space:
mode:
authorLeah Neukirchen <leah@vuxu.org>2017-10-18 16:28:57 +0200
committerLeah Neukirchen <leah@vuxu.org>2017-10-18 16:28:57 +0200
commitd3d95470cd01ffc022099df2b01914b3649934e2 (patch)
treef34232278b5dbaab6213957f70e51a7bf83a6f05
parent5f506f6f8d12037f3b216c92e8142fc68daf4106 (diff)
downloadpds-d3d95470cd01ffc022099df2b01914b3649934e2.tar.gz
pds-d3d95470cd01ffc022099df2b01914b3649934e2.tar.xz
pds-d3d95470cd01ffc022099df2b01914b3649934e2.zip
add -g for guarding matches HEAD master
-rwxr-xr-xpds33
1 files changed, 27 insertions, 6 deletions
diff --git a/pds b/pds
index d20f403..ff6d725 100755
--- a/pds
+++ b/pds
@@ -2,13 +2,15 @@
 # pds - parallel data substitution (doing 80% of sed 120% as well)
 
 USAGE = <<'EOF'
-pds [-i[BAK]] [-0] [-A] [-r] [-p] [-t] [-w] [-c[CHECK]] [-n[NTH]]
+pds [-i[BAK]] [-0] [-A] [-g] [-r] [-p] [-t] [-w] [-c[CHECK]] [-n[NTH]]
     PATTERN REPLACEMENT [PATTERN REPLACEMENT]... -- FILES...
              replaces each PATTERN with REPLACEMENT in the input, simultaneously
 
   -i[BAK]    edit files in place (backup with suffix BAK if supplied)
   -0         work on NUL terminated lines
   -A         work on whole file at once
+  -g         guarded replacement: uses additional PATTERN for each REPLACEMENT,
+             the first needs to match as regexp anywhere on the line
   -r         enable regex for PATTERN and backreferences for REPLACEMENT
              \& for the match, \1..\9 for n-th backreference, \c to clear line
   -p         only print lines with replacements
@@ -27,6 +29,7 @@ def fatal(msg)
 end
 
 iflag = nil
+gflag = false
 rflag = false
 nullflag = true
 nflag = []
@@ -46,6 +49,8 @@ until done
   case arg
   when /\A-i/
     iflag = $'
+  when "-g"
+    gflag = true
   when "-r"
     rflag = true
   when "-p"
@@ -76,15 +81,21 @@ until done
         break
       end
 
-      from = arg
+      if gflag
+        guard = arg
+        from = ARGV.shift
+      else
+        guard = nil
+        from = arg
+      end
       to = ARGV.shift
       if !to
         STDERR.puts "no replacement for '#{from}'"
         exit 1
       end
 
-      replacements << [from, to]
-      replacements << [to, from]  if tflag
+      replacements << [guard, from, to]
+      replacements << [guard, to, from]  if tflag
 
       arg = ARGV.shift
     }
@@ -98,9 +109,17 @@ if replacements.empty?
   fatal "no pattern given\n#{USAGE}"
 end
 
+gx = replacements.map { |x|
+  begin
+    x[0] && Regexp.new(x[0])
+  rescue RegexpError
+    fatal "invalid regex: #{$!}"
+  end
+}
+
 rx = replacements.map { |x|
   begin
-    rflag ? Regexp.new(x[0]) : Regexp.quote(x[0])
+    rflag ? Regexp.new(x[1]) : Regexp.quote(x[1])
   rescue RegexpError
     fatal "invalid regex: #{$!}"
   end
@@ -155,11 +174,13 @@ ARGV.each { |file|
       replace = nil
 
       rx.each_with_index { |r, i|
+        next  if gx[i] && !line.match(gx[i])
+
         if m = line.match(r, offset)
           if !leftmost || m.offset(0).first < leftmost.first
             leftmost = m.offset(0)
             matched = m
-            replace = replacements[i][1]
+            replace = replacements[i][2]
           end
         end
       }