Find and increment at each occurence of string (loop)

I created script (sh shell) to generate vlc playlist based on some data files. All works fine so far except one string I do not know how to handle with.

VLCSTART='<vlc:id>'
VLCV=0
VLCEND='</vlc:id>'
echo -e $'\n'$'\t'$'\t'$'\t'$'\t'\$VLCSTART$VLCV$VLCEND

Output file contains several occurences of this:

        <track>
            <location>http://ts://</location>
            <title>name</title>
            <extension application="http://www.videolan.org/vlc/playlist/0">
                <vlc:id>0</vlc:id>
                <vlc:option>network-caching=1000</vlc:option>
            </extension>
        </track>

I need to create loop to increment each occurrence of '0' +1 in string '<vlc:id>0</vlc:id>' but the first occurrence has to stay '0'.

I am not good at loops, still learning.... :slight_smile:

Hello TiedCone,

Following may help you in same, I have created a custom file with some more input as follows.

cat testtest123
        <track>
            <location>http://ts://</location>
            <title>name</title>
            <extension application="VideoLAN - 404 not found">
                <vlc:id>0</vlc:id>
                <vlc:option>network-caching=1000</vlc:option>
            </extension>
        </track>
        <track>
            <location>http://ts://</location>
            <title>name</title>
            <extension application="VideoLAN - 404 not found">
                <vlc:id>0</vlc:id>
                <vlc:option>network-caching=1000</vlc:option>
            </extension>
        </track>
        <track>
            <location>http://ts://</location>
            <title>name</title>
            <extension application="VideoLAN - 404 not found">
                <vlc:id>0</vlc:id>
                <vlc:option>network-caching=1000</vlc:option>
            </extension>
        </track>
        <track>
            <location>http://ts://</location>
            <title>name</title>
            <extension application="VideoLAN - 404 not found">
                <vlc:id>0</vlc:id>
                <vlc:option>network-caching=1000</vlc:option>
            </extension>
        </track>

Then following code may help.

awk 'BEGIN{B=0} /<vlc:id>/{A=$0;sub(/>.*/,">",$0);sub(/.*</,"<",A);print $0 B A;B++;next} 1' testtest123

Output will be as follows.

        <track>
            <location>http://ts://</location>
            <title>name</title>
            <extension application="VideoLAN - 404 not found">
                <vlc:id>0</vlc:id>
                <vlc:option>network-caching=1000</vlc:option>
            </extension>
        </track>
        <track>
            <location>http://ts://</location>
            <title>name</title>
            <extension application="VideoLAN - 404 not found">
                <vlc:id>1</vlc:id>
                <vlc:option>network-caching=1000</vlc:option>
            </extension>
        </track>
        <track>
            <location>http://ts://</location>
            <title>name</title>
            <extension application="VideoLAN - 404 not found">
                <vlc:id>2</vlc:id>
                <vlc:option>network-caching=1000</vlc:option>
            </extension>
        </track>
        <track>
            <location>http://ts://</location>
            <title>name</title>
            <extension application="VideoLAN - 404 not found">
                <vlc:id>3</vlc:id>
                <vlc:option>network-caching=1000</vlc:option>
            </extension>
        </track>

Thanks,
R. Singh

1 Like

You are fast mate. Thanks, perfect solution. :slight_smile: I have another one...

Assume tha last occurrence of <vlc:id>50</vlc:id> has value 50 I need to create the same amount of lines:

            <vlc:item tid="0"/>
            <vlc:item tid="1"/>
            <vlc:item tid="2"/>
...
            <vlc:item tid="50"/>

:slight_smile:

Since it is a loop, and assuming $VLCV has been set to 0 outside the loop, just append after the echo -e command

VLCV=$(( $VLCV + 1 ))

hth

Hello TiedCone,

Following may help you in same.

awk -vLINES=`cat Input_file | wc -l` 'BEGIN{B=0;C=0} /<vlc:id>/{A=$0;sub(/>.*/,">",$0);sub(/.*</,"<",A);print $0 B A;B++;if(LINES/8==B){while(C<=B-1){print $0 C A;C++}};next } 1'  Input_file

Output will be as follows.

        <track>
            <location>http://ts://</location>
            <title>name</title>
            <extension application="VideoLAN - 404 not found">
                <vlc:id>0</vlc:id>
                <vlc:option>network-caching=1000</vlc:option>
            </extension>
        </track>
        <track>
            <location>http://ts://</location>
            <title>name</title>
            <extension application="VideoLAN - 404 not found">
                <vlc:id>1</vlc:id>
                <vlc:option>network-caching=1000</vlc:option>
            </extension>
        </track>
        <track>
            <location>http://ts://</location>
            <title>name</title>
            <extension application="VideoLAN - 404 not found">
                <vlc:id>2</vlc:id>
                <vlc:option>network-caching=1000</vlc:option>
            </extension>
        </track>
        <track>
            <location>http://ts://</location>
            <title>name</title>
            <extension application="VideoLAN - 404 not found">
                <vlc:id>3</vlc:id>
                <vlc:id>0</vlc:id>
                <vlc:id>1</vlc:id>
                <vlc:id>2</vlc:id>
                <vlc:id>3</vlc:id>
                <vlc:option>network-caching=1000</vlc:option>
            </extension>
        </track>

NOTE: Here I am considering that your Input_file will have 8 lines of set means it will always start from tag

<track>

and end with tag </track> within 8 lines in it each tag.

Thanks,
R. Singh

@sea: That was my first thought as well, but the requestor uses sh , so VLCV=$(expr $VLCV + 1) might be more suitable.

@TiedCone: Please open a new thread for a new request. Where do you get the 50 from?

This is not what I want to achieve. :slight_smile:
Lines:

<vlc:item tid="0"/>

are outside of <track></track>.

This is completely different string but its values have to match values of

<vlc:id></vlc:id>

so the output will look like this:

        <track>
            <location>http://ts:/</location>
            <title>name</title>
            <extension application="http://www.videolan.org/vlc/playlist/0">
                <vlc:id>0</vlc:id>
                <vlc:option>network-caching=1000</vlc:option>
            </extension>
        </track>
...
        <track>
            <location>http://ts:/</location>
            <title>name</title>
            <extension application="http://www.videolan.org/vlc/playlist/0">
                <vlc:id>50</vlc:id>
                <vlc:option>network-caching=1000</vlc:option>
            </extension>
        </track>
    </trackList>
    <extension application="http://www.videolan.org/vlc/playlist/0">
            <vlc:item tid="0"/>
            <vlc:item tid="1"/>
            <vlc:item tid="2"/>
            ...
            <vlc:item tid="50"/>

So need code for generating these lines:

<vlc:item tid="0"/>

@RudiC
'50' is the number of last occurrence of <vlc:id>0</vlc:id> in file and is flexible depends on input data file.

@ RudiC, in that case, why not either VLCV=$[ $VLCV + 1 ] or even just ((VLCV++)) ?

---------- Post updated at 12:32 ---------- Previous update was at 12:30 ----------

@ TiedCone:

C=0 # Counter
while [ $C -le $VLCV ]
do  echo "<vlc:item tid=\"$C\"/>"
    C=$(( $C + 1 ))
done

hth

Hello Tiedcone,

Following may help you in same, not tested though.

 awk -vLINES=`cat Input_file | wc -l` 'BEGIN{B=0;C=0} /<vlc:id>/{A=$0;sub(/>.*/,">",$0);sub(/.*</,"<",A);S=S?S ORS $0 B A:$0 B A;print $0 B A;B++;next} /<extension application/{print $0 ORS S;next} 1' Input_file

Thanks,
R. Singh

So - it's in $VLCV, and you are echo ing all the text? add

i=0
while [ "$i" -le "$VLCV" ]
  do echo "           <vlc:item tid=\"$i\"/>"
     i=$(expr $i + 1)
  done

to your script.

Thanks to all. Unfortuantelly I was not able to use above examples but I found another way to achieve my goal by using grep and sed. I just simply copied existing

<vlc:id>0</vlc:id>

strings and replaced what needs to be replaced. :slight_smile: