替换文件每一行中的非匹配模式字符串

时间:2021-01-11 14:00:34

标签: awk sed

来自以下文件:

 1  PARSING IN CURSOR #140499 dep=0 tim=4217919222030  sqlid='ftf4q8xj38z7k' 
 2  WAIT #1404991: nam='SQL*Net message' ela= 1 tim=4217919224736
 3  WAIT #1404991: nam='SQL*Net message' ela= 655 tim=4217919225409
 4  PARSING IN CURSOR #140499 dep=0 tim=4217919225606  sqlid='9fufagwmu041b'  
 5  WAIT #1404991: nam='redo log sync' ela= 1 tim=4217919225677
 6  WAIT #1404991: nam='redo log sync' ela= 736 tim=4217919226432
 7  PARSING IN CURSOR #140499 dep=0 tim=4217919226577  sqlid='bzdm0nbr7c036'
 8  WAIT #1404990: nam='SQL*Net message' ela= 1 tim=4217919226665
 9  WAIT #1404990: nam='SQL*Net message' ela= 2027 tim=4217919228710
10  WAIT #1404991: nam='SQL*Net message' ela= 1 tim=4217919228849
11  PARSING IN CURSOR #140499 dep=1 tim=4217919225606  sqlid='9fufagwmu041b' 
12  WAIT #1404991: nam='PGA memory operation' ela= 603 tim=4217919229470
13  WAIT #1404991: nam='PGA memory operation' ela= 1 tim=4217919229647
14  WAIT #1404991: nam='PGA memory operation' ela= 521 tim=4217919230185 

我想显示所有内容,但对于在 SQL*Net messagenam=' 之间不匹配 ' ela= 的行内的字符串,我希望将这些字符串替换为 Other DB operation (并在这些字符串前后保留 nam='' ela=):

 1  PARSING IN CURSOR #140499 dep=0 tim=4217919222030  sqlid='ftf4q8xj38z7k' 
 2  WAIT #1404991: nam='SQL*Net message' ela= 1 tim=4217919224736
 3  WAIT #1404991: nam='SQL*Net message' ela= 655 tim=4217919225409
 4  PARSING IN CURSOR #140499 dep=0 tim=4217919225606  sqlid='9fufagwmu041b' 
 5  WAIT #1404991: nam='Other DB operation' ela= 1 tim=4217919225677
 6  WAIT #1404991: nam='Other DB operation' ela= 736 tim=4217919226432
 7  PARSING IN CURSOR #140499 dep=0 tim=4217919226577  sqlid='bzdm0nbr7c036' 
 8  WAIT #1404990: nam='SQL*Net message' ela= 1 tim=4217919226665
 9  WAIT #1404990: nam='SQL*Net message' ela= 2027 tim=4217919228710
10  WAIT #1404991: nam='SQL*Net message' ela= 1 tim=4217919228849
11  PARSING IN CURSOR #140499 dep=1 tim=4217919225606  sqlid='9fufagwmu041b'  
12  WAIT #1404991: nam='Other DB operation' ela= 603 tim=4217919229470
13  WAIT #1404991: nam='Other DB operation' ela= 1 tim=4217919229647
14  WAIT #1404991: nam='Other DB operation' ela= 521 tim=4217919230185 

是否有 sed 或 awk 命令可以让我轻松地做到这一点?

4 个答案:

答案 0 :(得分:0)

使用这个 Perl 单行:

perl -pe 'next if /nam=.SQL[*]Net message. ela=/; s/(nam=)\S.*\s+(ela=)/${1}'\''Other DB operation'\'' ${2}/' in_file > out_file

Perl one-liner 使用这些命令行标志:
-e :告诉 Perl 查找内嵌代码,而不是在文件中。
-p :一次循环输入一行,默认情况下将其分配给 $_。在每次循环迭代后添加 print $_

(nam=)(ela=) 周围的括号将这些模式捕获到变量 $1$2 中。
. 是任意字符。
.* 是任意字符,重复 0 次或更多次。
\S 是非空白字符。
\s 是一个空白字符。

另见:
perldoc perlrun: how to execute the Perl interpreter: command line switches
perldoc perlre: Perl regular expressions (regexes)
perldoc perlre: Perl regular expressions (regexes): Quantifiers; Character Classes and other Special Escapes; Assertions; Capture groups
perldoc perlrequick: Perl regular expressions quick start

答案 1 :(得分:0)

awk '$0!~/SQL\*Net/{gsub(/nam=.*ela/, "nam='\''Other DB operation'\''",$0)} 1' input_file.txt

给予

 1  PARSING IN CURSOR #140499 dep=0 tim=4217919222030  sqlid='ftf4q8xj38z7k' 
 2  WAIT #1404991: nam='SQL*Net message' ela= 1 tim=4217919224736
 3  WAIT #1404991: nam='SQL*Net message' ela= 655 tim=4217919225409
 4  PARSING IN CURSOR #140499 dep=0 tim=4217919225606  sqlid='9fufagwmu041b'  
 5  WAIT #1404991: nam='Other DB operation'= 1 tim=4217919225677
 6  WAIT #1404991: nam='Other DB operation'= 736 tim=4217919226432
 7  PARSING IN CURSOR #140499 dep=0 tim=4217919226577  sqlid='bzdm0nbr7c036'
 8  WAIT #1404990: nam='SQL*Net message' ela= 1 tim=4217919226665
 9  WAIT #1404990: nam='SQL*Net message' ela= 2027 tim=4217919228710
10  WAIT #1404991: nam='SQL*Net message' ela= 1 tim=4217919228849
11  PARSING IN CURSOR #140499 dep=1 tim=4217919225606  sqlid='9fufagwmu041b' 
12  WAIT #1404991: nam='Other DB operation'= 603 tim=4217919229470
13  WAIT #1404991: nam='Other DB operation'= 1 tim=4217919229647
14  WAIT #1404991: nam='Other DB operation'= 521 tim=4217919230185 

答案 2 :(得分:0)

 sed -ri '/Net message/!{/PARSING/!s/(^.*'"'"')(.*)('"'"'.*)/\1Other DB operation\3/}' file

使用sed。对于所有不包含“Net message”(!)然后不包含“PARSE”的行,将该行分成 3 个部分,并用该行替换第一部分,然后是“Other DB Operation”和第三部分。

答案 3 :(得分:0)

使用 GNU awk 来匹配第三个参数:

$ awk '
    match($0,/(.*nam=\047)([^\047]*)(\047 ela.*)/,a) && (a[2] != "SQL*Net message") {
        $0 = a[1] "Other DB operation" a[3]
    }
1' file
 1  PARSING IN CURSOR #140499 dep=0 tim=4217919222030  sqlid='ftf4q8xj38z7k'
 2  WAIT #1404991: nam='SQL*Net message' ela= 1 tim=4217919224736
 3  WAIT #1404991: nam='SQL*Net message' ela= 655 tim=4217919225409
 4  PARSING IN CURSOR #140499 dep=0 tim=4217919225606  sqlid='9fufagwmu041b'
 5  WAIT #1404991: nam='Other DB operation' ela= 1 tim=4217919225677
 6  WAIT #1404991: nam='Other DB operation' ela= 736 tim=4217919226432
 7  PARSING IN CURSOR #140499 dep=0 tim=4217919226577  sqlid='bzdm0nbr7c036'
 8  WAIT #1404990: nam='SQL*Net message' ela= 1 tim=4217919226665
 9  WAIT #1404990: nam='SQL*Net message' ela= 2027 tim=4217919228710
10  WAIT #1404991: nam='SQL*Net message' ela= 1 tim=4217919228849
11  PARSING IN CURSOR #140499 dep=1 tim=4217919225606  sqlid='9fufagwmu041b'
12  WAIT #1404991: nam='Other DB operation' ela= 603 tim=4217919229470
13  WAIT #1404991: nam='Other DB operation' ela= 1 tim=4217919229647
14  WAIT #1404991: nam='Other DB operation' ela= 521 tim=4217919230185

请注意,上面正在执行字符串操作,因此将您要查找的字符串中的字符以及您替换它的字符视为文字,因此您无需转义正则表达式元字符(例如 .*) 或反向引用(例如 &\<number>)。