Read file and change a 0 to a 1 in output

<key>ExcludeSimpleHostnames</key>
                <integer>0</integer>
                <key>FTPPassive</key>

Need simple command that will change the 0 to a 1 in this file when I grep it, but only for this integer key directly after the ExcludeSimpleHostnames key.

I got this output code from running:

grep -iA2  excludesimplehostnames /Library/Preferences/SystemConfiguration/preferences.plist 

check syntax on '&&' in if condition, otherwise, should work

PREVLINE=""
CURRLINE=""
while read line
do
    PREVLINE=$CURRLINE
    CURRLINE=$line
    CONTAINSKEY=`echo $PREVLINE|grep -c ExcludeSimpleHostnames`
    CONTAINSINT=`echo $CURRLINE|grep -c "<integer>0<"`
    if [ $CONTAINSKEY -eq 1 && $CONTAINSINT -eq 1 ]
    then
         echo $line|sed 's/0/1/' >> outputfile
    else
         echo $line >> outputfile
    fi
done < infile

Here's another solution, and this assumes you DO NOT want the other lines in the file printed. It uses awk's "range" operator.

awk '/<key>ExcludeSimpleHostnames<\/key>/,/<key>/ { sub(/>0</,">1<"); print; }'

Here's another way that prints out everything else:

awk 's { sub(/>0</,">1<");s=0; } /<key>ExcludeSimpleHostnames</ { s=1;} { print; }'

The second one consists of 3 awk pattern/program pairs. The first is for when you are the target line, and s is non-zero one input line after the 2nd pattern/program, which set s to non-zero. The third pattern/program prints out every line.

<key>Proxies</key>
            <dict>
                <key>ExceptionsList</key>
                <array>
                    <string>*.local</string>
                    <string>169.254/16</string>
                </array>
                <key>ExcludeSimpleHostnames</key>
                <integer>1</integer>
                <key>FTPPassive</key>
                <integer>1</integer>
                <key>HTTPEnable</key>
                <integer>1</integer>
                <key>HTTPPort</key>
                <integer>8080</integer>
                <key>HTTPProxy</key>
                <string>192.168.171.4</string

I need to write

<key>ExcludeSimpleHostnames</key>
                <integer>1</integer>

To this section of this file like shown in the first example. There will be a lot more text in the file, but I am only concerned with the sections that are formatted like the one shown in the first example. They will always start with <key>Proxies</key>. There may be multiple <key>Proxies</key> sections, I will need the

<key>ExcludeSimpleHostnames</key>
                <integer>1</integer>

code inserted into all those sections as shown in the first example.

---------- Post updated at 04:30 PM ---------- Previous update was at 04:23 PM ----------

This is very urgent.. I'm sure it is some use of awk, the simpler the better.. I just need to insert two lines:

<key>ExcludeSimpleHostnames</key>
<integer>1</integer>

to be inserted the next line after </array> I suppose could work.

INPROXIES=0
CONTAINSKEY=0
CONTAINSARRAYEND=0
while read line
do
    # output the current line
    echo $line >> output
    # test if we're inside <key>Proxies
    if [ $INPROXIES -eq 0 ]
    then
      # set flag only if in current line matches, next 'if' keeps it set
      CONTAINSKEY=`echo $line|grep -c "<key>Proxies</key>"`
    fi

    # test if flag is set
    if [ $CONTAINSKEY -eq 1 ]
    then
        # set flag 
        INPROXIES=1
        CONTAINSARRAYEND=`echo $line|grep -c "<\array>"`
        if [ $CONTAINSARRAYEND -eq 1 ]
        then
          # output new vals
          echo "       <key>ExcludeSimpleHostnames</key>" >> output
          echo "                                  <integer>1</integer>" >> output
          # reset flags
          INPROXIES=0 
          CONTAINSKEY=0
          CONTAINSARRAYEND=0
        fi
    fi
done < infile

this code isn't tested, but it seems like it should do it.

glev,

When you say "inserted", is it correct that you mean, "create a new file B with all the lines from A except changing those that I indicated" ? If that's the case, you simply need my second awk script from above. http://www.unix.com/emergency-unix-linux-support-help-me/120363-read-file-change-0-1-output.html\#post302357772

I mean that I need it to check for the lines that I mentioned
<key>ExcludeSimpleHostnames</key>
<integer>1</integer>
In every section that starts with <key>Proxies</key>

and if it doesn't exist there to place it there the line after </array>

I want it to write this info to the file, not to create a new one.

This doesn't happen. A new file is ALWAYS written and the old file replaced. This is simply the method used by operating systems for "text" files of any sort.

The second problem is that you want to check "if it doesn't exist" and then place it there. Well, you can't really do that in one pass. The best solution is to Put it there and remove any existing ones.

So:

awk '
   /<key>ExcludeSimpleHostnames</ { s=1; next; } 
   s && /<integer>[0-9]*</integer>/ { s=0; next;} 
   /<key>Proxies</ { p=1 } 
   p && /<\/array>/ {
                print; 
                print "<key>ExcludeSimpleHostnames</key>";
                print "<integer>1</integer>"; 
                p=0; next; } 
    { print; }'

If you want to use the integer value found in this proxy section, you're kind of screwed -- you have to either do backtracking or two passes or create a metastructure of all the data and write it out again to XML. That's because you want the ExcludeSimpleHostnames key to follow the array in the output, but the input, it might occur later.

Code

sed '<integer>,</integer> {
s/0/1/g
}
' input_file

---------- Post updated at 08:18 AM ---------- Previous update was at 08:16 AM ----------

or more accurte:-

sed 'ExcludeSimpleHostnames,\/integer {
s/0/1/g
}
' input_file.txt