単一行または複数行の2つの文字列の間でデータを取得するsedコマンドのbashスクリプト

単一行または複数行の2つの文字列の間でデータを取得するsedコマンドのbashスクリプト

いくつかのファイル(.v.gz)があります。ファイルに存在するデータは次のとおりです。

通事論:

module **module_name**(out, In, clk, rst )
statement 1
statement 2
   :
   :
statement n
endmodule

実際のデータは

文書

module mod_reg_lif(out, In, clk, rst )  #
statement 1
statement 2
   :
   :
statement n
endmodule

module 
    dff_reg_net(out, In, clk, rst )  
statement 1
statement 2
   :
   :
statement n
endmodule

module 
   dat_log_out (out, In, clk, rst ) 
statement 1
statement 2
   :
   :
statement n
endmodule

module rest_wire_lib  (out, In, clk, rst ) 
statement 1
statement 2
   :
   :
statement n
endmodule

実際のファイルには、同様の種類の複数のデータが含まれています。

module switch(in1, datainready1, atainready) 
always @(posedge clk) 
begin 
  if (reset == 1)
  begin 
    counter<= 0;
      datainreadyl<= 0;
    if(counter ==0) 
      dataoutready<= 0;
   end 
endmodule

ここで、スイッチはモジュール名です。

上記の例では、module_namesが次のようになっていることを確認してください。mod_reg_lif, dat_log_out, dff_reg_net, Rest_wire_lib,

検討した後基準寸法〜のように モジュール名(同じ行または次の行に)まで同じ行または次の行にある場合、これが発生します。出力では、私は次のモジュール名が欲しい。

mod_reg_lif   
dat_log_out 
dff_reg_net
rest_wire_lib  

私が得た結果は何ですか?

mod_reg_lif   
rest_wire_lib 

moduleとmodule_nameの両方が同じ行にあるため、出力に記載されているすべてのデータを取得できません。

私のバッシュコードは

for file in *.v.gz;
do
  zgrep -A1 "^module" "$file" | sed -n -e 's/^\(module \)*\(.*(.*)\).*$/\2/p' | cut -f1 -d"(" > $(basename "$file" .v.gz).txt
done

私を修正してくださいsed -n -e 's/^(モジュール)(。(。)).$/\2/p'コマンドを修正する方法がわかりません。

ps:問題について質問がある場合はコメントを残してください。

答え1

おそらくこれはあなたが望むものでしょう。 GNU awkを使用して複数文字、RS単語の境界を表し、略語を使用します。RT\<\s[[:space:]]

$ zcat *.v.gz | awk -v RS='\\<module\\s+[^[:space:](]+' 'RT{$0=RT; print $2}'
mod_reg_lif
dff_reg_net
dat_log_out
rest_wire_lib

答え2

提示した例では、角かっこはモジュール名の後にのみ表示され、モジュール名にスペースはありません。その場合は、次のようにできます。

$ zgrep -oP '\S+\s*(?=\()' file.v.gz 
mod_reg_lif(
dff_reg_net
dat_log_out 
rest_wire_lib   

あなたの例にitがあるので、追加が(あります。私の考えでは、誤字だと思います。mod_reg_lif(module mod_reg_lif((out, In, clk, rst )

ここでのアイデアはgrepのPCREモードを使用しています期待されるこれにより、空白以外の文字(\S+)、ゼロ個以上の空白文字(\s*)、および((?=\())を見つけることができます。

オプションを含むgrepがない場合は、-P次のことができます。

$ zgrep -o '[^[:blank:]]*[[:blank:]]*(' file.v.gz | sed 's/ *(//g'
mod_reg_lif
dff_reg_net
dat_log_out
rest_wire_lib

括弧が使用できず、ファイルに括弧が表示される可能性がある別の場所があるため、モジュール名を識別するmoduleために文字列を使用する必要がある場合は、次のことを試すことができます。

$ zcat file.v.gz | perl -007ne 'print join("\n",(/\bmodule\s*(\S+?)\s*\(/gs)),"\n"; '
mod_reg_lif
dff_reg_net
dat_log_out
rest_wire_lib

これにより、ファイル全体がメモリにロードされるため、大容量ファイルの場合に問題が発生する可能性があります。


awk最後に、を使用してレコード区切り文字を2つの空の文字列に設定することもできます。これにより、awkは、レコード(行)が2つの連続した改行文字として定義されている「短絡モード」で動作します。次に、行の最初の角かっこの後のすべての項目を削除し、2番目のフィールドを印刷します。

$ zcat file.v.gz | awk 'BEGIN{RS=""}{sub(/\(.*/,"");print $2; }'
mod_reg_lif
dff_reg_net
dat_log_out
rest_wire_lib

関連情報