このコマンドラインで<(echo)をどのように理解しますか?

このコマンドラインで<(echo)をどのように理解しますか?

この行は、最初の列に基づいてファイルを縮小します。

awk '{if($1==x){i=i" "$2}else{if(NR>1){print i};i=$0};x=$1;y=$2}' test.cov <(echo)

入力する:

1001  hisk01
1001  hisk02
1001  hisk03
1002  hisk04
1002  hisk05
1002  hisk06
1003  hisk07
1003  hisk08

出力:

1001 hisk01 hisk02 hisk03
1002 hisk04 hisk05 hisk06
1003 hisk07 hisk08

<(echo)うまくいきますが、ここではどのように機能するのかわかりません。誰でも私を助けることができますか?

ありがとう

答え1

<(GNU Bourne-Again Shell(Bash)の機能である「プロセス交換」です。 POSIXにはありません。

プロセス置換は、コマンドライン引数に拡張される構文です。ターゲットプログラムは、パラメータをファイル名のように開くことができます。結果ファイル記述子は、括弧の間の構文に示されているコマンドパイプラインに接続されます。

言い換えれば、<(echo)と同じ単語に展開されます/magic/path/53。プログラムはこのパスを受け取り、入力ファイルとして開くと読み取るパイプ記述子を取得しますecho

echo効果は何ですか?空行が生成されます。

唯一の違いは

some-command <(echo)

そして

some-command /dev/null

<(echo)空行だけが生成され、何も生成されませ/dev/nullん。

空行を含むファイルのパス名であると仮定できます<(echo)(パス名が出力ではなく入力用にのみ開かれている場合)。

ここでのアイデアは、入力に終了空の行がawk含まれていることを確認するようです。つまり、入力ファイルに何があっても、空白行test.covが追加されます。連続した行間の状態を維持するため、スクリプトのロジックに必要です。i内容は前の行によって異なり、次の行が到着すると印刷される変数があります。最後の行について計算された内容はi印刷されないため、余分な空行がなければ、最後の行は完全には処理されません<(echo)test.cov

test.cov終了改行文字が欠落している場合<(echo)は、単に提供されません。 awk の複数の入力ファイルは単に一緒にリンクされ、単一文字ストリームを形成しません。改行文字の有無にかかわらず、最初のファイルの末尾でレコードが区切られ、2 番目のファイルに対して新しいレコードが生成されます。

周辺シェルからプロセス交換機能への依存関係を削除する簡単な方法があります。

awk '{if($1==x){i=i" "$2}else{if(NR>1){print i};i=$0};x=$1;y=$2}; END {print i}'

それだけです!END累積レコードを印刷するためのブロックを追加します。 ifは、処理されたレコードがないため定義されていないことを意味し、空の値を印刷するため、テストするi必要はありません。ただし、この場合は空白行が出力され、使用するとこれを防ぐことができます。NR > 1NR == 0iEND {if (i) print i}

答え2

iこれにより、変数内のバッファの最後の内容のみが出力されます。これにより空行が生成されるため、awkはその空行を再度実行して変数にバッファリングさiれた値を印刷します。代わりに<(echo)そのブロックを使用できますEND{ print i }

また、見ることができます私の答え入力がソート/ソートされていない両方の場合、他の方法でこれを行うにはどうすればよいですか?

答え3

あなたが要求した質問に対する答えを得ましたが、参考にしたいことをする最も一般的な方法の1つは次のとおりです。

$ awk -v ORS= '$1!=prev{print rec; ORS=RS; rec=prev=$1} {rec=rec OFS $2} END{print rec}' file
1001 hisk01 hisk02 hisk03
1002 hisk04 hisk05 hisk06
1003 hisk07 hisk08

関連情報