Reputation: 43
I have the following file:
<CamcorderProfiles cameraId="0">
<EncoderProfile quality="720p" fileFormat="mp4" duration="30">
<Video codec="h264"
bitRate="8000000"
width="1280"
height="720"
frameRate="30" />
<Audio codec="aac"
bitRate="96000"
sampleRate="48000"
channels="1" />
</EncoderProfile>
<EncoderProfile quality="1080p" fileFormat="mp4" duration="30">
<Video codec="h264"
bitRate="12000000"
width="1920"
height="1080"
frameRate="30" />
<Audio codec="aac"
bitRate="96000"
sampleRate="48000"
channels="1" />
</EncoderProfile>
</CamcorderProfiles>
<CamcorderProfiles cameraId="1">
<EncoderProfile quality="720p" fileFormat="mp4" duration="30">
<Video codec="h264"
bitRate="8000000"
width="1280"
height="720"
frameRate="30" />
<Audio codec="aac"
bitRate="96000"
sampleRate="48000"
channels="1" />
</EncoderProfile>
<EncoderProfile quality="1080p" fileFormat="mp4" duration="30">
<Video codec="h264"
bitRate="12000000"
width="1920"
height="1080"
frameRate="30" />
<Audio codec="aac"
bitRate="96000"
sampleRate="48000"
channels="1" />
</EncoderProfile>
</CamcorderProfiles>
Here is my code:
camerastart=$(sed -n '{/<CamcorderProfiles cameraId="0">/=}' $file)
cameraend=$(sed -n $camerastart',$ {/<\/CamcorderProfiles>/=}' $file)
camera1080pstart=$(sed -n $camerastart','$cameraend' {/<EncoderProfile quality="1080p" fileFormat="mp4" duration="30">/=}' $file)
When I print the variables, I get the correct line numbers on all but camera1080p_start, which comes up blank.
camerastart = 3
cameraend = 29
camera1080pstart =
If I change up the first line of the code to cameraId="1"
, then I do get proper results for that case.
camerastart = 31
cameraend = 57
camera1080pstart = 45
If I change the code so the first two variables are hardcoded in, I do get the proper output of 17
camera1080pstart.
camerastart="3"
cameraend="29"
camera1080pstart=$(sed -n $camerastart','$cameraend' {/<EncoderProfile quality="1080p" fileFormat="mp4" duration="30">/=}' $file)
Anyone know what is going on?
Upvotes: 1
Views: 231
Reputation: 43
The solution that worked for me is:
camerastart=$(sed -n '{/<CamcorderProfiles cameraId="0">/=}' $file | head -1)
cameraend=$(sed -n $camerastart',$ {/<\/CamcorderProfiles>/=}' $file | head -1)
camera1080pstart=$(sed -n $camerastart','$cameraend' {/<EncoderProfile quality="1080p" fileFormat="mp4" duration="30">/=}' $file | head -1)
Upvotes: 0
Reputation: 98078
Change the second command to:
cameraend=$(sed -n $camerastart',$ {/<\/CamcorderProfiles>/=}' $file | head -1)
because it returns multiple line numbers. However, this might not be the best way to tackle this particular problem.
Upvotes: 1
Reputation: 204035
Here's a script that will find and print the line you want to change:
$ cat tst.awk
BEGIN{ FS = "\"" }
/<CamcorderProfiles cameraId=/ { cameraId = $2 }
/<EncoderProfile quality=/ { quality = $2 }
/bitRate="12000000"/ {
if ( (cameraId == "0") && (quality == "1080p") ) {
print NR, "this is the line I want to change:"
print
}
}
$ awk -f tst.awk file
17 this is the line I want to change:
bitRate="12000000"
If you need to be able to invoke it with different cameraId and/or quality and/or any other values, that's a trivial tweak.
If you tell us in what way you want to change the line the script finds, that's trivial too.
EDIT: updated script based on OPs comments below.
$ cat tst.awk
BEGIN{ FS = "\"" }
/<CamcorderProfiles cameraId=/ { cameraId = $2 }
/<EncoderProfile quality=/ { quality = $2 }
/bitRate="12000000"/ {
if ( (cameraId == "0") && (quality == "1080p") ) {
sub(/12000000/,"20000000")
}
}
{ print }
$ awk -f tst.awk file > tmpfile
$ diff file tmpfile
17c17
< bitRate="12000000"
---
> bitRate="20000000"
If you want to update the original file, just run it as:
awk -f tst.awk file > tmpfile && mv tmpfile file
Upvotes: 0