从文件传递时变量在 awk 中不接受

Ren*_*nga 3 awk text-processing

我正在逐行读取文件。每行看起来像这样:

xxyu: JHYU_IOPI
Run Code Online (Sandbox Code Playgroud)

每行都传递给 awk,如下所示。我想打印匹配模式的上一行;我可以用 grep 来实现这一点,并想知道我在 awk 中哪里犯了错误。

#!/bin/bash
while read i
do
 awk '/$i/{print a}{a=$0}' ver_in.txt
done<in.txt
Run Code Online (Sandbox Code Playgroud)

我也尝试过这个:

#!/bin/bash
while read i
do
 awk -v var="$i" '/var/{print a}{a=$0}' jil.txt
done<in.txt
Run Code Online (Sandbox Code Playgroud)

编辑:在得到建议不要使用 sh read 后使用 awk 。我的输入和期望的输出如下所示:

编辑 1:编辑@Ed Morton awk 脚本的输入,如下所示

输入文件:cat文件

/* ----------------- AIX_RUN_WATCH ----------------- */ 

insert_job: AIX_RUN_WATCH   job_type: BOX 
owner: root
permission: 
date_conditions: 1
days_of_week: su
start_times: "22:00"
alarm_if_fail: 1
alarm_if_terminated: 1
group: app
send_notification: 0
notification_emailaddress: 


 /* ----------------- AIX_stop ----------------- */ 

 insert_job: AIXstop   job_type: CMD 
 box_name: AIX_RUN_WATCH
 command: ls
 machine: cfg.mc
 owner: root
 permission: 
 date_conditions: 0
 box_terminator: 1
 std_out_file: ">> /tmp/${AUTOSERV}.${AUTO_JOB_NAME}.$(date +%Y%m%d).stdout"
 std_err_file: ">> /tmp/${AUTOSERV}.${AUTO_JOB_NAME}.$(date +%Y%m%d).stderr"
 alarm_if_fail: 1
 alarm_if_terminated: 1
 group: app
 send_notification: 1


 /* ----------------- AIX_start ----------------- */ 

 insert_job: AIX_start   job_type: CMD 
 box_name: AIX_RUN_WATCH
 command: ls
 machine: cfg.mc
 owner: root
 permission: 
 date_conditions: 0
 box_terminator: 1
 std_out_file: ">> /tmp/${AUTOSERV}.${AUTO_JOB_NAME}.$(date +%Y%m%d).stdout"
 std_err_file: ">> /tmp/${AUTOSERV}.${AUTO_JOB_NAME}.$(date +%Y%m%d).stderr"
 alarm_if_fail: 1
 alarm_if_terminated: 1
 group: app

   cat targets
     box_name: AIX_RUN_WATCH
Run Code Online (Sandbox Code Playgroud)

预期产出 -

 box_name: AIX_RUN_WATCH
 insert_job: AIX_stop
 insert_job: AIX_start
Run Code Online (Sandbox Code Playgroud)

αғs*_*нιη 7

第一次尝试时,您需要使用双引号进行 shell 变量扩展,然后对 awk$运算符进行转义,以防止它被 shell 扩展,但请注意,如果变量$i包含特殊字符(如\, ),这样使用会破坏 awk /。[我现在将跳过修复您的命令的一个或多个其他问题]。

while read i
do
 awk "/$i/{print a}{a=\$0}" ver_in.txt
done<in.txt
Run Code Online (Sandbox Code Playgroud)

对于第二次尝试,您需要对当前行使用正则表达式匹配或字符串匹配,例如使用正则表达式匹配(部分正则表达式匹配):

while read i
do
 awk -v var="$i" '$0 ~ var{print a}{a=$0}' jil.txt
done<in.txt
Run Code Online (Sandbox Code Playgroud)

或字符串匹配(完整字符串匹配),例如:

while read i
do
 awk -v var="$i" '$0==var{print a}{a=$0}' jil.txt
done<in.txt
Run Code Online (Sandbox Code Playgroud)

现在,谈论您尝试使用它们来打印匹配模式的上一行的命令,您可以使用 awk 完成所有操作,然后使用 shell 循环停止;这里我们正在进行完整的字符串匹配:

awk 'NR==FNR { str[$0]; next }
($0 in str) && prev!="" { print prev } { prev=$0 }' in.txt ver_in.txt
Run Code Online (Sandbox Code Playgroud)

或进行部分正则表达式匹配:

awk 'NR==FNR { patt[$0]; next }
{ for(ptrn in patt) if($0 ~ ptrn && prev!="") print prev; prev=$0 }' in.txt ver_in.txt
Run Code Online (Sandbox Code Playgroud)

或进行部分字符串匹配:

awk 'NR==FNR { strings[$0]; next }
{ for(str in strings) if(index($0, str) && prev!="") print prev; prev=$0 }' in.txt ver_in.txt
Run Code Online (Sandbox Code Playgroud)

或进行完整的正则表达式匹配:

awk 'NR==FNR { patt[$0]; next }
{ for(ptrn in patt) if($0 ~ "^"ptrn"$" && prev!="") print prev; prev=$0 }' in.txt ver_in.txt
Run Code Online (Sandbox Code Playgroud)