0

I trying to solve following problem. With great helps of others here, I can write and understand simple do loop in bash scripting.

Now I try to do this:

In "mein_directory" directory I need following first to

create let say 10 subdirectories, with name subdirectories1.... subdirectories10

then I need to copy file to each subdirectories,

and then I need to enter in to each subdirectories and change specific word in file that has been copy from main directory.

And this is my main problem at the moment, because I need to change a the specific word is actually a number and I need to change this number of an increment multibly by number of subdirectory

so my code looks like this:

#!/bin/bash
increment=10

for i in {1..10}; do
    mkdir subdirectory_$i;
done


for d in */; do
    cp FILE "$d";
done

for j in {1..10}; do
    cd subdirectory_$j/
    increment=increment*$j
    sed -i 's/old_word old_digit/old_word old_digits+increment/g' CONTROL
    cd ../;
done

So let say the in file "FILE" in subdirectory_1

I need to change following

from

Paul 10 to Paul 20

And in subdirectory_2

from

Paul 10 to Paul 30

Please does anybody know how to around this?

Thanks a lot

g_p
  • 18,504
  • hi pavol - again ;)

    as the file you are copying seems to be a template - couldn't you just replace your 'Paul 10' with sth more special, so you simply can replace that always same thing?

    in sed you then also can use your e.g. $increment

    – rkn Jan 10 '15 at 01:23

1 Answers1

2

Let us say the old_word marker is known. We can then use grep to obtain the number from the original file:

NUM=$(grep -Po -m1 '(?<=old_word )\d+'  FILE)
  • This uses Perl regular expressions. It says that old_world should precede some digits, but should not be considered part of the actual match.
  • -o -m1 tells grep to print only the matched section (the number), and only the first such match.

Then you can combine your copying with the modification:

for i in {1..10}
do 
    NEXT_NUM=$((NUM + i*increment))
    mkdir subdirectory_$i
    sed -r 's/(old_word )'$NUM'/\1'$NEXT_NUM'/' FILE > subdirectory_$i/FILE
done

Things to consider:

  • sed is not very good at arithmetic, so if you want to do it within the expression itself, consider using Perl or Awk.
  • You cannot directly do a=1*2 in shell scripts to perform arithmetic. You need to enclose the expression in $(( )): a=$((1*2)), or use keywords like let.
  • Variables are not expanded in single quotes, but regular expressions frequently contain characters which have special meaning, so it is safer to use single quotes for the expression, and temporarily leave them to add in our variable.
  • The parentheses around (old_word ) mark this as an sub expression, which you can refer to later using \1 (as can be seen in the replacement).
muru
  • 197,895
  • 55
  • 485
  • 740
  • Thank you many times for your important points. I am new to bash scripting, so I don't consider the expression of basic aritmetic operation in bash script. I also find out http://askubuntu.com/questions/76808/how-to-use-variables-in-sed-command that using "" you can use varible inside sed command. So thank you many times your answer helps me – Pavol Namer Jan 10 '15 at 13:08