ファイルから渡されると、awkでは変数は許可されません。

ファイルから渡されると、awkでは変数は許可されません。

ファイルを一行ずつ読み込んでいます。各行は次のようになります。

xxyu: JHYU_IOPI

各行は以下のようにawkに渡されます。パターンに一致する前の行を印刷したいです。 grepを使ってこれを行うことができ、awkでどこでミスをするのか知りたいです。

#!/bin/bash
while read i
do
 awk '/$i/{print a}{a=$0}' ver_in.txt
done<in.txt

私もこれを試しました:

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

編集: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

予想出力 -

 box_name: AIX_RUN_WATCH
 insert_job: AIX_stop
 insert_job: AIX_start

ベストアンサー1

最初の試みでは、シェル変数拡張に二重引用符を使用してから、$awk演算子をエスケープしてシェル拡張を防ぐ必要があります。ただし、変数にawk$iなどの特殊文字(たとえば、、)が含まれていることに注意してください。 [今は、コマンドに関連する1つ以上の他の問題を解決することをスキップします]。\/

while read i
do
 awk "/$i/{print a}{a=\$0}" ver_in.txt
done<in.txt

2番目の試みでは、現在の行で正規表現一致または文字列一致を使用する必要があります。たとえば、正規表現一致(部分正規表現一致)を使用します。

while read i
do
 awk -v var="$i" '$0 ~ var{print a}{a=$0}' jil.txt
done<in.txt

または、次の文字列一致(完全な文字列一致)です。

while read i
do
 awk -v var="$i" '$0==var{print a}{a=$0}' jil.txt
done<in.txt

パターンに一致する前の行を印刷するために使用したいコマンドについて話したら、awkを使用してすべての操作を実行してから、完全な文字列一致を実行するシェルループの使用を停止できます。

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

または部分正規表現マッチングを実行します。

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

または部分文字列マッチングを実行します。

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

または、完全正規表現マッチングを実行します。

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

おすすめ記事