0

I'm needing help setting up a bash script for initializing some BC's in a file. Ideally, my program would iterate through each line and:
1) Read in BC type - (wall, outlet, inlet).
2) Change "type" field based on appropriate BC type.

Unfortunately, my program seems to replace all type fields in Step 2 instead of only the type field associated with the correct BC.

I think this has something to do with the sed command operating over the whole file instead of just the $line variable.

while IFS= read -r line || [[ -n "$line" ]]; do                                         #go through each line of T2 file
        if [[ $line == *wall_* ]]                               #if wall_*
        then
                echo "attempted to assign wall_*"
                var=1 #wall                                     #Go down 2 lines
        elif [[ $line == *velocity-inlet* ]]
        then
                echo "attempted to assign outflow"
                var=2 #inlet
        elif [[ $line == *outflow* ]]
        then
                var=3 #outlet
        fi
        echo $var
        if [[ $line == *type* && $var == 1 ]]
        then
                sed -i 's/.*type.*/type                 zeroGradient/' 0/T3
                echo "Attempted wall zeroGradient"
        elif [[ $line == *type* && $var == 2 ]]
        then
                sed -i 's/.*type.*/type                 fixedValue\nvalue               uniform (3 0 0)/' 0/T3

        elif [[ $line == type* && $var == 3 ]]
        then
                sed -i 's/.*type.*/type                 zeroGradient/' 0/T3

        fi
        sed -i '/nFaces*/d' 0/T3                        #Deletes irrelevant stuff from boundary file copy
        sed -i '/startFace*/d' 0/T3
done <0/T3.

For example, it is supposed to change:

velocity-inlet_1  
{   
    type            patch;  
    nFaces          336;  
    startFace       75515;  
}  
outflow_2    
{  
    type            patch;  
    nFaces          136;  
    startFace       75851;  
}   

To:

velocity-inlet_1  
    {  
        type            fixedValue;  
        value           uniform (3 0 0);  
    }  
    outflow_2  
    {  
        type            zeroGradient;
    }  

But instead changes it wrongly changes it to:

velocity-inlet_1
    {
        type            fixedValue;
        value           uniform (3 0 0);
    }
    outflow_2
    {
        type            fixedValue;
        value           uniform (3 0 0);
    }

Help me stack overflow, you're my only hope.

  • Welcome to SO, great that you showed nice sample of your input, output and what you tried for too. Could you please elaborate conditions by which you need to new data as it is not clear. – RavinderSingh13 Jun 21 '18 at 14:51
  • I'm sorry I think I don't fully understand what you're asking. I'm just trying to take the input data I've given in Code Block 2 and turn it to the desired output data I've described in Code Block 3. Unfortunately, my script is changing the entire file instead of only the specific line/BC I'm supposed to be operating on. – Patrick Williams Jun 21 '18 at 15:02
  • Your `sed -i /x/y/ 0/T3` statements will operate on the entire 0/T3 file, not just the line you're currently looking at. – HardcoreHenry Jun 21 '18 at 15:08
  • @HardcoreHenry. Yeah I was wondering if there's a way to get sed to only operate on the $line variable and not the whole file. – Patrick Williams Jun 21 '18 at 15:38
  • You can... (you can do `echo $line | sed "s/x/y/`), but that spits the modified line into stdout -- it doesn't change the file. Once read, there is no link between the string in `$line`, and the file itself. – HardcoreHenry Jun 21 '18 at 15:58
  • if you can specify the line number, you can set it as a condition in the substitute command. sed takes lineno (c.f. [here](https://unix.stackexchange.com/questions/70878/replacing-string-based-on-line-number) <== ). You could also just skip sed, and print each line out (edited if necessary) so that the script makes a new version of the file rather than doing an in-place edit. When done, save off the original as a backup, and move the new one in over the old. – Paul Hodges Jun 21 '18 at 20:28

1 Answers1

0

You have a few issues. sed will effect a whole line by default, and you're not telling it which line to modify in the first place. You're also modifying a file as you read it. I might go with something like this:

var="none"
while IFS= read -r line; do
        if [[ "$line" =~ "wall" ]]; then
             var=wall
        elif [[ "$line" =~ "velocity-inlet" ]]; then
             var=inlet
        fi

        if [[ "$line" =~ "type" && "$var" == "wall" ]]; then
              echo "$line" | sed 's|\(type *\).*|\1zeroGradient|'
        elif [[ "$line" =~ "type" && "$var" == "inlet" ]]; then
              echo "$line" | sed 's|\(type *\).*|\1uniform (3 0 0)|'
        else
              echo "$line"
        fi
done

And then do

 script.sh < 0/T3 > 0/T3.mod

You can of course modify this to read/write from particular files as well, and you can avoid sed (see here...)

HardcoreHenry
  • 5,909
  • 2
  • 19
  • 44