I have a file with two lines, The numbers in the file when written to will vary ranging from 01 to over 100. For example:
ln -s /dev/vg_ifmx_test_core4/rdsk_web59 /dev/itest17/dbs_web59
/usr/sbin/lvcreate -L 2048 -n rdsk_web59 /dev/vg_ifmx_test_core4
I need to increment the ending number (in this case it is 59) by one.
Resulting in:
ln -s /dev/vg_ifmx_test_core4/rdsk_web60 /dev/itest17/dbs_web60
/usr/sbin/lvcreate -L 2048 -n rdsk_web60 /dev/vg_ifmx_test_core4
Notice how /dev/vg_ifmx_test_core4
does not get incremented,
So is it possible to take in account the scenario of:
ln -s /dev/vg_ifmx_test_core4/rdsk_web04 /dev/itest17/dbs_web04
/usr/sbin/lvcreate -L 2048 -n rdsk_web04 /dev/vg_ifmx_test_core4
Resulting in
ln -s /dev/vg_ifmx_test_core4/rdsk_web05 /dev/itest17/dbs_web05
/usr/sbin/lvcreate -L 2048 -n rdsk_web05 /dev/vg_ifmx_test_core4
The lines in the file can vary (the path that is) such as:
/usr/sbin/lvcreate -L 2048 -n dbs_saleitem_f105 /dev/vg_ifmx_test_std3
ln -s/dev/vg_ifmx_test_std3/rdbs_saleitem_f105/dev/itest7/saleitem_f105
Would result in:
/usr/sbin/lvcreate -L 2048 -n dbs_saleitem_f106 /dev/vg_ifmx_test_std3
ln -s/dev/vg_ifmx_test_std3/rdbs_saleitem_f106/dev/itest7/saleitem_f106
So using something as perl -i -pe '/ln -s /dev/vg_ifmx_test_core4/rdsk_web/
would not be possible since the path is not always the same in the file.
Is there a way to use sed or awk/perl to create an expression to do this? I am new to shell scripting and using these commands. Thanks in advance!
CodePudding user response:
perl -pe 'if ($. == 1) {
($n) = ($m) = /([0-9] )$/;
$m;
s/$n/$m/g;
} else {
s/$n(?= )/$m/;
}' file
CodePudding user response:
With GNU awk for the third arg to match()
:
awk '
match($0,/(.*[^0-9])([0-9] )( .*[^0-9])([0-9] )/,a) {
a[2]
a[4] = (NR==1 ? 1 : 0)
$0 = a[1] a[2] a[3] a[4]
}
{ print }
' file
ln -s /dev/vg_ifmx_test_core4/rdsk_web60 /dev/itest17/dbs_web60
/usr/sbin/lvcreate -L 2048 -n rdsk_web60 /dev/vg_ifmx_test_core4
To write the output back to the original file just change awk
to awk -i inplace
.
CodePudding user response:
$ cat file
ln -s /dev/vg_ifmx_test_core4/rdsk_web04 /dev/itest17/dbs_web04
/usr/sbin/lvcreate -L 2048 -n rdsk_web04 /dev/vg_ifmx_test_core4
awk '{
gsub(/web[0-9][0-9]/,
"web"sprintf("%0.2d",gensub(/.*web([0-9][0-9]).*/, "\\1",1) 1))
}1' file
ln -s /dev/vg_ifmx_test_core4/rdsk_web05 /dev/itest17/dbs_web05
/usr/sbin/lvcreate -L 2048 -n rdsk_web05 /dev/vg_ifmx_test_core4
CodePudding user response:
I would prefer to either set a variable that can be trivially changed, or use a templating language to create the file. Either seems simpler to maintain and less brittle than awk/perl/etc.
If "file" will be executed by a shell:
N=60
ln -s /dev/vg_ifmx_test_core4/rdsk_web$N /dev/itest17/dbs_web$N
/usr/sbin/lvcreate -L 2048 -n rdsk_web$N /dev/vg_ifmx_test_core4
Now it is trivial to change the first line.
Or, if you want to keep the original format:
# generate the file from template
mkfile(){
cat <<EOD
ln -s /dev/vg_ifmx_test_core4/rdsk_web$1 /dev/itest17/dbs_web$1
/usr/sbin/lvcreate -L 2048 -n rdsk_web$1 /dev/vg_ifmx_test_core4
EOD
}
# ...
mkfile 60 >/path/to/file
# ...
for n in 59 60 04 05; do
# ...
mkfile $n >/path/to/file
# ...
fi