Increment with bash
Asked Answered
M

5

25

I'm stuck trying to increment a variable in an .xml file. The tag may be in a file 100 times or just twice. I am trying to add a value that will increment the amount several times. I have included some sample code I am working on, but when I run the script it will only place a one and not increment further. Advice would be great on what I'm doing wrong.

for xmlfile in $(find $DIRECTORY -type f -name \*.xml); do
  TFILE="/tmp/$directoryname.$$"
  FROM='><process>'
  TO=' value\=""><process>'
  i=0
  while [ $i -lt 10 ]; do
    i=`expr $i + 1`
    FROM='value\=""'
    TO='value\="'$i'"'
  done
  sed "s/$FROM/$TO/g" "$xmlfile" > $TFILE && mv $TFILE "$xmlfile"
done

The while loop was something I just placed to test the code. It will insert the <process> but it will not insert the increment.

My end goal:

<process>value="1"</process>
<process>value="2"</process>
<process>value="3"</process>
<process>value="4"</process>

And so on as long as <process> is present in the file it needs to increment.

Menashem answered 14/11, 2012 at 19:50 Comment(0)
W
21

For a proper increment in bash, use a for loop (C style) :

n=10
for ((i=1; i<=n; i++)) {
    printf '<process>value="%d"</process>\n' $i
}

OUTPUT

<process>value="1"</process>
<process>value="2"</process>
<process>value="3"</process>
<process>value="4"</process>
<process>value="5"</process>
<process>value="6"</process>
<process>value="7"</process>
<process>value="8"</process>
<process>value="9"</process>
<process>value="10"</process>

NOTE

expr is a program used in ancient shell code to do math. In Posix shells like bash, use $(( expression )). In bash and ksh93, you can also use (( expression )) or let expression if you don't need to use the result in an expansion.

EDIT

If I misunderstood your needs and you have a file with blank values like this :

<process>value=""</process>

try this :

$ perl -i -pe '$c++; s/<process>value=""/<process>value"$c"/g' file.xml
<process>value"1"</process>
<process>value"2"</process>
<process>value"3"</process>
<process>value"4"</process>
<process>value"5"</process>
<process>value"6"</process>
<process>value"7"</process>

-i switch edit the file for real, so take care.

Weisbart answered 14/11, 2012 at 21:30 Comment(0)
W
36

I just tested your code and it seems to correctly increment i.

You could try changing your increment syntax from:

i=`expr $i + 1`

To

i=$((i+1))
Whop answered 14/11, 2012 at 19:54 Comment(4)
or just (( i++ )). Good luck to all.Maas
neither work. Now it prints to .xml file <process>value="10"</process> for everything and does not incrementSquires
@CuriousGeorge: if you're always getting 10, then: A. where is it getting set to that value (OR are somehow the values from 0-9 are being discarded or skipped), B. how can it even print that when you have a condition that i -lt 10, "i lessThan 10" (Maybe you should try (( i++ < 10 ))? Learn to turn on the shell debuging/trace feature with set -vx near the top and set +vx to turn off the trace. This will show you the line (or block) of code that will be executed, and then each executed step with values substituted for the variables. Good luck.Maas
@CuriousGeorge: your while loop makes sure that i is incremented to 10, then you insert that value via sed. So yes, that is the expected behavior from your code.Kylie
W
21

For a proper increment in bash, use a for loop (C style) :

n=10
for ((i=1; i<=n; i++)) {
    printf '<process>value="%d"</process>\n' $i
}

OUTPUT

<process>value="1"</process>
<process>value="2"</process>
<process>value="3"</process>
<process>value="4"</process>
<process>value="5"</process>
<process>value="6"</process>
<process>value="7"</process>
<process>value="8"</process>
<process>value="9"</process>
<process>value="10"</process>

NOTE

expr is a program used in ancient shell code to do math. In Posix shells like bash, use $(( expression )). In bash and ksh93, you can also use (( expression )) or let expression if you don't need to use the result in an expansion.

EDIT

If I misunderstood your needs and you have a file with blank values like this :

<process>value=""</process>

try this :

$ perl -i -pe '$c++; s/<process>value=""/<process>value"$c"/g' file.xml
<process>value"1"</process>
<process>value"2"</process>
<process>value"3"</process>
<process>value"4"</process>
<process>value"5"</process>
<process>value"6"</process>
<process>value"7"</process>

-i switch edit the file for real, so take care.

Weisbart answered 14/11, 2012 at 21:30 Comment(0)
K
12

This is the simplest way to increment a variable in bash:

i=0
((++i))
Keelby answered 1/8, 2014 at 17:59 Comment(1)
when using set -e, you should—at least when a zero is the first value (i=0)—perform pre-increment instead, i.e. ((++i)). Otherwise your program will stop right at the first increment, because the exit code will be 1. Quite surprising. See unix.stackexchange.com/questions/32250/…Cowry
R
4

This also works.

Declaring the variable as an integer.

declare -i i=0

Then later you can increment like so:

i+=1
Raman answered 15/8, 2019 at 16:19 Comment(1)
imho the best answer, since it seems not to have any issues with exit codes like the increment operator.Cowry
F
1

Use awk:

awk '{gsub( "value=\"\"", "value=" i++ ); print }' i=1 input-file

This will replace the string value="" with value="1", value="2", etc. You can easily change the start value and the increment ( eg ..."value=" i ); i+=5; print )

Farquhar answered 14/11, 2012 at 20:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.