GʀᴜᴍᴘʏCᴀᴛ
GʀᴜᴍᴘʏCᴀᴛ

Reputation: 8908

Increment with bash

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.

Upvotes: 25

Views: 61261

Answers (5)

Cory Klein
Cory Klein

Reputation: 55620

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

i=0
((++i))

Upvotes: 12

dskrad
dskrad

Reputation: 108

This also works.

Declaring the variable as an integer.

declare -i i=0

Then later you can increment like so:

i+=1

Upvotes: 4

Gilles Qu&#233;not
Gilles Qu&#233;not

Reputation: 184985

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.

Upvotes: 21

William Pursell
William Pursell

Reputation: 212198

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 )

Upvotes: 1

sampson-chen
sampson-chen

Reputation: 47269

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))

Upvotes: 36

Related Questions