BASH:找到第一个字符串后在文件中找到一个字符串

Von*_*ddy 2 bash sed

请多多包涵...

我有一个大的xml文件,我需要找到一个字符串"JOBNAME = 9027",然后找到包含"TASKTYPE"后面的行并更改该行.

所以我必须更改JOBNAME = 9027之后的TASKTYPE行.有几百个JOBNAME和TASKTYPE线,所有线的数量都不相同.

我试过sed,awk和bash无济于事.我确信有办法做到这一点,但它正在逃避我.

例:

JOBNAME="MYSAP#SDOR-SG-D-LATECODED-0927"
            JUL="1"
            JUN="1"
            MAR="1"
            MAXDAYS="0"
            MAXRERUN="0"
            MAXRUNS="0"
            MAXWAIT="0"
            MAY="1"
            MULTY_AGENT="N"
            NODEID="sappr2"
            NOV="1"
            OCT="1"
            PARENT_FOLDER="MYSAP#SSDOR-D-SG-LATECODED-0927"
            PRIORITY="10"
            RETRO="0"
            RULE_BASED_CALENDAR_RELATIONSHIP="O"
            RUN_AS="MYSAP"
            SEP="1"
            SHIFT="Ignore Job"
            SHIFTNUM="+00"
            SUB_APPLICATION="MYSAP"
            SYSDB="0"
            TASKTYPE="Job"
Run Code Online (Sandbox Code Playgroud)

Joh*_*024 7

使用sed

尝试:

sed '/JOBNAME.*0927/,/TASKTYPE/ {s/TASKTYPE.*/TASKTYPE="NewJob"/}' largefile
Run Code Online (Sandbox Code Playgroud)

这产生了输出:

JOBNAME="MYSAP#SDOR-SG-D-LATECODED-0927"
            JUL="1"
            JUN="1"
            MAR="1"
            MAXDAYS="0"
            MAXRERUN="0"
            MAXRUNS="0"
            MAXWAIT="0"
            MAY="1"
            MULTY_AGENT="N"
            NODEID="sappr2"
            NOV="1"
            OCT="1"
            PARENT_FOLDER="MYSAP#SSDOR-D-SG-LATECODED-0927"
            PRIORITY="10"
            RETRO="0"
            RULE_BASED_CALENDAR_RELATIONSHIP="O"
            RUN_AS="MYSAP"
            SEP="1"
            SHIFT="Ignore Job"
            SHIFTNUM="+00"
            SUB_APPLICATION="MYSAP"
            SYSDB="0"
            TASKTYPE="NewJob"
Run Code Online (Sandbox Code Playgroud)

这个怎么运作:

  • /JOBNAME.*0927/,/TASKTYPE/ {...}对于以匹配正则表达式的行开头并以匹配JOBNAME.*0927后的第一行结束的行组执行花括号中的命令TASKTYPE.

  • s/TASKTYPE.*/TASKTYPE="NewJob"/用以下TASKTYPE内容替换后面的内容TASKTYPE="NewJob".

使用awk

这个awk脚本使用相同的逻辑:

awk '/JOBNAME.*0927/,/TASKTYPE/ {sub(/TASKTYPE.*/, "TASKTYPE=\"NewJob\"")} 1' largefile
Run Code Online (Sandbox Code Playgroud)

这个怎么运作:

  • /JOBNAME.*0927/,/TASKTYPE/ {...}

    对于以匹配正则表达式的行开头并以匹配JOBNAME.*0927后的第一行结束的行组执行花括号中的命令TASKTYPE.

  • sub(/TASKTYPE.*/, "TASKTYPE=\"NewJob\"")

    这执行替换.

  • 1

    与sed不同,awk默认情况下不会打印任何内容.这1是打印全线的awk简洁速记.

    更详细地说,1是一个逻辑条件.它评估为"真实".我们没有指定任何与该条件相关的行动.因此,awk执行默认操作,即print-the-line : print $0.