0

I am trying to replace the old 3par LUNs with new Vmax LUNs. Can someone help me make a script to ease the task?

Is it possible to create 2 files, one file having the 3par LUNs, the other file having all the new VMAX LUNS? Then replace all the content of mulipath.conf.

Currently I am using:

sed -i "s/360002ac000000000000001f20001add7/60002ac000000000000001f20001accb/g" multipath.conf

Can someone help make the command work?

sed "s/`cat 3par.txt`/`cat vmax.txt`/g" multipath.conf
terdon
  • 242,166
jojo
  • 1
  • 2
    Please [edit] your question and show us an example of your input file and your desired output. What wold these 3par and vmax files contain? One line? Many lines? Why would having the data in a file help if you just want to replace two strings? – terdon Aug 27 '19 at 14:00
  • 1
    Sorry I don't know anything about 3par, LUNs, or Vmax. Can you show us what you are trying to do. Also don't use back ticks, they are hard to use, and have been replaced with $() e.g. sed "s/$(cat 3par.txt)/$(cat vmax.txt)/g" multipath.conf – ctrl-alt-delor Aug 27 '19 at 14:08
  • Are you asking "Can someone help make the following command work? ..."? – ctrl-alt-delor Aug 27 '19 at 14:12
  • It looks like you have a file with a set of strings (60002ac000000000000001f20001accb being one of them) that you want to use as replacements, and another file with a set of strings (360002ac000000000000001f20001add7 being one of them) that you want to search for and replace in your multipath.conf file. Is this correct? – fra-san Aug 27 '19 at 14:13

2 Answers2

1
$ perl -e '
   open(F1,"<",shift);
   open(F2,"<",shift);
   while(<F1>) {
     chomp; # strip trailing \n from input file.
     $new=<F2>;
     chomp $new;
     print "s/$_/$new/g\n"
   }' file1.txt file2.txt
s/360002ac000000000000001f20001add7/60002ac000000000000001f20001accb/g
s/360002ac000000000000001f20001add8/60002ac000000000000001f20001accc/g
s/360002ac000000000000001f20001add9/60002ac000000000000001f20001accd/g
s/360002ac000000000000001f20001ade0/60002ac000000000000001f20001acce/g

This could be (and was written as) a one-liner, I added linefeeds to make it more readable.

if file1.txt do not have the same number of lines as file2.txt, this script will produce bogus output for any lines in one file that don't have a corresponding line in the other. So don't do that.

To apply these changes to your multipath.conf file run the above perl one-liner and redirect the output to a file (e.g. sedscript.sed) and then run:

sed -f sedscript.sed multipath.conf

Verify that the generated sed script does what you want and then either redirect the output to a new file, or use sed's -i option to do an "in-place" edit on multipath.conf itself. Make a backup first, of course and copy it somewhere safe outside the reach of -i (or even -i.bak).

sample input files are:

$ cat file1.txt 
360002ac000000000000001f20001add7
360002ac000000000000001f20001add8
360002ac000000000000001f20001add9
360002ac000000000000001f20001ade0

$ cat file2.txt 
60002ac000000000000001f20001accb
60002ac000000000000001f20001accc
60002ac000000000000001f20001accd
60002ac000000000000001f20001acce

BTW, with a little more work this perl one-liner could be made to read in file1 and file2, construct an array of s/old/new/g operations, and then apply them to a third file (such as multipath.conf)

For example:

#!/usr/bin/perl

# run with three arguments:
# $1 = file containing old patterns
# $2 = file containing replacements
# $3 = file to modify

# THIS SCRIPT IS A CRUDE, MINIMALIST EXAMPLE AND CONTAINS NO ERROR
# CHECKING/HANDLING CODE AT ALL. USE AT OWN RISK.

use strict;
use File::Slurp;

# hash to store the search patterns and their replacements.
my %regex=();

open(F1,"<",shift);
open(F2,"<",shift);
while(<F1>) {
  chomp; # strip trailing \n from input file.
  my $new=<F2>;
  chomp $new;
  # qr// pre-compiles the regular expression, so it doesn't have to be
  # compiled on every pass through the loop.
  $regex{qr/$_/} = $new;
};
close(F1);
close(F2);

my $f3=shift;

my @file3=read_file($f3);

# transform and overwrite the third file.
open(F3,">",$f3);
foreach (@file3) {
  foreach my $key (keys %regex) {
        s/$key/$regex{$key}/g;
  }
  print F3;
};
close(F3);
cas
  • 78,579
0

Given two files named "old"...

$ cat old
old1
old2
old3

and "new"

$ cat new
new1
new2
new3

You can create a scriptfile for sed as follows:

$ paste old new | while read old new; do printf "s/%s/%s/g\n" "$old" "$new"; done |tee sedfile
s/old1/new1/g
s/old2/new2/g
s/old3/new3/g

And use that file with sed:

sed -f sedfile mulipath.conf > review-this.conf
markgraf
  • 2,860