带有变量和行号限制的Sed

带有变量和行号限制的Sed,sed,Sed,我有以下文件: <CamcorderProfiles cameraId="0"> <EncoderProfile quality="720p" fileFormat="mp4" duration="30"> <Video codec="h264" bitRate="8000000" width="1280" height="720"

我有以下文件:

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

如果我将代码的第一行改为
cameraId=“1”
,那么对于这种情况,我确实会得到正确的结果

camerastart = 31
cameraend = 57
camera1080pstart = 45
如果我更改代码,使前两个变量硬编码,我会得到
17
camera1080pstart的正确输出

camerastart="3"
cameraend="29"

camera1080pstart=$(sed -n $camerastart','$cameraend' {/<EncoderProfile quality="1080p" fileFormat="mp4" duration="30">/=}' $file)
camerastart=“3”
cameraend=“29”
camera1080pstart=$(sed-n$camerastart','$cameraend'{/=}'$文件)

有人知道发生了什么吗?

这里有一个脚本,可以找到并打印您要更改的行:

$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"

下面是一个脚本,它将查找并打印要更改的行:

$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"

将第二个命令更改为:

cameraend=$(sed -n $camerastart',$ {/<\/CamcorderProfiles>/=}' $file | head -1)
cameraend=$(sed-n$camerastart',${/=}'$file | head-1)

因为它返回多个行号。但是,这可能不是解决此特定问题的最佳方法。

将第二个命令更改为:

cameraend=$(sed -n $camerastart',$ {/<\/CamcorderProfiles>/=}' $file | head -1)
cameraend=$(sed-n$camerastart',${/=}'$file | head-1)

因为它返回多个行号。但是,这可能不是解决这个特定问题的最佳方法。

对我有效的解决方案是:

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)
camerastart=$(sed-n'{/=}'$file | head-1)
cameraend=$(sed-n$camerastart',${/=}'$file | head-1)
camera1080pstart=$(sed-n$camerastart','$cameraend'{/=}'$file | head-1)

对我有效的解决方案是:

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)
camerastart=$(sed-n'{/=}'$file | head-1)
cameraend=$(sed-n$camerastart',${/=}'$file | head-1)
camera1080pstart=$(sed-n$camerastart','$cameraend'{/=}'$file | head-1)


是的,您使用了错误的工具。sed是一个很好的工具,用于在单行上进行简单替换,对于任何其他文本处理任务,您都应该使用awk。告诉我们您正在尝试做什么,并发布一些与示例输入匹配的预期输出,有人会告诉您正确的方法。我要做的是编辑xml文件的特定行。例如,将EncoderProfile quality=“1080p”标记和cameraId=“0”标记内的bitRate=“12000000”行更改为其他内容。不知何故,我需要深入研究多个标记层,以便在正确的标记中更改行。我发布了一个小的awk脚本,让您开始,但您需要告诉我们您希望以何种方式更改找到的行,并提供其他信息以进一步。是的,您使用了错误的工具。sed是一个很好的工具,用于在单行上进行简单替换,对于任何其他文本处理任务,您都应该使用awk。告诉我们您正在尝试做什么,并发布一些与示例输入匹配的预期输出,有人会告诉您正确的方法。我要做的是编辑xml文件的特定行。例如,将EncoderProfile quality=“1080p”标记和cameraId=“0”标记内的bitRate=“12000000”行更改为其他内容。不知何故,我需要深入研究多个标记层,以便在正确的标记中更改行。我发布了一个小的awk脚本,让您开始,但您需要告诉我们您希望以何种方式更改找到的行,并提供其他信息以进一步。我尝试在变量中获取第17行的原因是,这样我可以运行
sed-i'17 s/12000000/20000000/”文件
在该行。我可以在您的脚本中正确地执行此操作吗?当然可以,但是当您已经在处理目标行时,不需要获取行号。我现在将更新脚本,将12000000更改为20000000。我尝试在变量中获取第17行的原因是,我可以在该行上运行类似于
sed-I'17 s/12000000/20000000/”的文件。我可以在您的脚本中正确地执行此操作吗?当然可以,但是当您已经在处理目标行时,不需要获取行号。我现在将更新脚本,将12000000更改为20000000。您可能了解一些情况。那有什么用?仅返回第一个实例?是的,
head-1
返回其输入的第一行,因此您仅获得第一个实例。因此,如果您尝试迭代所有实例,您可以使用
grep-c
head
。您是个天才。成功了!我想最好是把
head-1
放在它们上面,以防存在多个实例。你可能会发现一些东西。那有什么用?仅返回第一个实例?是的,
head-1
返回其输入的第一行,因此您仅获得第一个实例。因此,如果您尝试迭代所有实例,您可以使用
grep-c
head
。您是个天才。成功了!我想最好是在所有的上面都加上
head-1
,以防存在多个实例。
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)