删除特定字符和长度之后的所有内容

  • 本文关键字:之后 字符 删除 bash shell
  • 更新时间 :
  • 英文 :


我想删除特定格式后的所有文本。

<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="&gt;" 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="&gt;" 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 正则表达式快速入门

相关内容

  • 没有找到相关文章

最新更新