我想删除特定格式后的所有文本。
<JOB APPLICATION="Daily" SUB_APPLICATION="Y#D5#4#M2F" JOBNAME="MLETTXXD-NONR_005" DESCRIPTION="" CREATED_BY="vpma" RUN_AS="ctmagt" CRITICAL="0" TASKTYPE="Dummy" NODEID="OPENFRAME" %%ENVIRONMENT MLETTXXD %%ORDERID %%RUNCOUNT %%JCL_STEP" CONFIRM="0" RETRO="0" MAXRERUN="0" AUTOARCH="1" MAXDAYS="0" MAXRUNS="0" TIMETO=">" JAN="1" FEB="1" MAR="1"
<INCOND NAME="PROD-A#D5#4#M2F-STRTDAYA-001-OK" ODATE="ODAT" AND_OR="A" />
<INCOND NAME="PROD-PS#P#D3#SU2SA@E-TIME0000-098-OK" ODATE="ODAT" AND_OR="A" />
删除JOBNAME="..."
之前和之后的所有字符串
输出应为
JOBNAME="MLETTXXD-NONR_005"
<INCOND NAME="PROD-A#D5#4#M2F-STRTDAYA-001-OK" ODATE="ODAT" AND_OR="A" />
<INCOND NAME="PROD-PS#P#D3#SU2SA@E-TIME0000-098-OK" ODATE="ODAT" AND_OR="A" />
我在下面尝试过,但没有发生第二awk
条件。
awk '/JOBNAME=/{print $4} | /INCOND/{print $2}' inputfile.txt
使用sed
$ sed s'/.*(JOBNAME[^ ]*).*/1/' input_file
JOBNAME="MLETTXXD-NONR_005"
<INCOND NAME="PROD-A#D5#4#M2F-STRTDAYA-001-OK" ODATE="ODAT" AND_OR="A" />
<INCOND NAME="PROD-PS#P#D3#SU2SA@E-TIME0000-098-OK" ODATE="ODAT" AND_OR="A" />
对 OP 当前awk
代码的一个简单修复:
$ awk '/JOBNAME=/{$0=$4}1' inputfile.txt
JOBNAME="MLETTXXD-NONR_005"
<INCOND NAME="PROD-A#D5#4#M2F-STRTDAYA-001-OK" ODATE="ODAT" AND_OR="A" />
<INCOND NAME="PROD-PS#P#D3#SU2SA@E-TIME0000-098-OK" ODATE="ODAT" AND_OR="A" />
笔记:
$0=$4
说用第 4 个字段的内容替换当前行- 假设 OP 的
/INCOND/
模式匹配是尝试打印其余的输入行,因此...... - 独立
1
说要打印当前行
这有一些限制:
- 假设
JOBNAME="..."
字符串始终位于行的第 4 个空格分隔字段中 - 不考虑单行中字符串的多个实例
- 假设字符串不包含任何空格
解决限制...
首先,我们将在输入中添加一个新行:
$ cat inputfile.txt
<JOB APPLICATION="Daily" SUB_APPLICATION="Y#D5#4#M2F" JOBNAME="MLETTXXD-NONR_005" DESCRIPTION="" CREATED_BY="vpma" RUN_AS="ctmagt" CRITICAL="0" TASKTYPE="Dummy" NODEID="OPENFRAME" %%ENVIRONMENT MLETTXXD %%ORDERID %%RUNCOUNT %%JCL_STEP" CONFIRM="0" RETRO="0" MAXRERUN="0" AUTOARCH="1" MAXDAYS="0" MAXRUNS="0" TIMETO=">" JAN="1" FEB="1" MAR="1"
<INCOND NAME="PROD-A#D5#4#M2F-STRTDAYA-001-OK" ODATE="ODAT" AND_OR="A" />
<INCOND NAME="PROD-PS#P#D3#SU2SA@E-TIME0000-098-OK" ODATE="ODAT" AND_OR="A" />
<JOB APPLICATION="Daily" JOBNAME="JOBNAME # 1" DESCRIPTION="" JOBNAME="Another Job" CREATED_BY="vpma"
一个GNU awk
的想法:
awk '
BEGIN { FPAT="\<JOBNAME="[^"]*"" } # define field pattern as JOBNAME="..."
NF { pfx="" # if we have a FPAT match then NF>0
for (i=1;i<=NF;i++) { # loop through our FPAT matches
printf "%s%s",pfx,$i # print each FPAT match to stdout
pfx=OFS
}
print "" # terminate the line of FPAT matches
next # go to next line of input
}
1 # print all lines that do not have a FPAT match
' inputfile.txt
注意:
FPAT
支持需要GNU awk
(这允许我们定义字段的格式;这取代了定义字段分隔符格式的FS
的使用)- 独立
1
假定 OP 想要打印与字符串JOBNAME="..."
不匹配的所有其他输入行(否则 OP 应更新示例输入以包含不应打印的行)
这将生成:
JOBNAME="MLETTXXD-NONR_005"
<INCOND NAME="PROD-A#D5#4#M2F-STRTDAYA-001-OK" ODATE="ODAT" AND_OR="A" />
<INCOND NAME="PROD-PS#P#D3#SU2SA@E-TIME0000-098-OK" ODATE="ODAT" AND_OR="A" />
JOBNAME="JOBNAME # 1" JOBNAME="Another Job"
使用这个 Perl 单行:
perl -pe 's{ .* ( JOBNAME="[^"]*" ) .* }{$1}x;' in_file > out_file
Perl 单行代码使用这些命令行标志:-e
:告诉 Perl 在内联中查找代码,而不是在文件中查找代码.-p
:一次循环一行输入,默认情况下将其分配给$_
。在每次循环迭代后添加print $_
。
正则表达式使用这些修饰符:/x
:为了可读性,忽略空格和注释。
s{ .* ( JOBNAME="[^"]*" ) .* }{$1};
:替换此模式:.*
- 任何字符中继器 0 次或更多次,后跟JOBNAME="[^"]*"
,它有[^"]*
-除"
以外的任何字符,重复 0 次或更多次,后跟.*
次。将此模式替换为$1
:第一个捕获组,即括号内匹配的任何内容。
另请参阅:perldoc perlrun
: 如何执行 Perl 解释器: 命令行开关perldoc perlre
: Perl 正则表达式 (regexes)perldoc perlre
: Perl 正则表达式 (regexes): 量词;角色职业和其他特殊逃生;断言;捕获组perldoc perlrequick
:Perl 正则表达式快速入门