GNU/Linux >> Linux の 問題 >  >> Linux

各行を前後に出力するコマンド

シェル関数。これは、<<< をサポートするすべてのシェルで機能します。 zsh と bash を含む here-strings。

xyz() { 
    while read line
    do 
        printf "%s " "$line"
        "[email protected]" <<<"$line"
    done
}
$ (echo "foo"; echo "bar") | xyz rev
foo oof
bar rab

ほとんどの場合、stdio バッファリングの動作方法が原因で、多くの問題が発生します。 Linux での回避策は、stdbuf を使用することです。 プログラムを作成し、coproc を使用してコマンドを実行すると、出力のインターリーブを明示的に制御できます。

以下は、コマンドが入力の各行の後に 1 行を出力することを前提としています。

#!/bin/bash
coproc stdbuf -i0 -o0 "[email protected]"
IFS=
while read -r in ; do
    printf "%s " "$in"
    printf "%s\n" "$in" >&${COPROC[1]}
    read -r out <&${COPROC[0]}
    printf "%s\n" "$out"
done

OPがプログラムへの入力の各行のみを最終的にする必要があるため、より一般的な解決策が必要な場合 すぐにではなく 1 行を出力する場合は、より複雑なアプローチが必要です。 read -t 0 を使用してイベント ループを作成します。 標準入力とコプロセスから読み取りを試みます。両方に同じ「行番号」がある場合は出力し、そうでない場合は行を保存します。イベント ループのいずれかのラウンドでどちらも準備ができていない場合に CPU の 100% を使用しないようにするには、イベント ループを再度実行する前に少し遅延を導入します。プロセスが部分的な行を出力する場合、さらに複雑になります。これらはバッファリングする必要があります。

このより一般的な解決策が必要な場合は、expect を使用してこれを記述します。これは、複数の入力ストリームでのパターン マッチングの処理が既に適切にサポートされているためです。ただし、これは bash/zsh ソリューションではありません。


この特定のケースでは、 perl を使用します :

printf '%s\n' foo bar | perl -Mopen=locale -lpe '$_ .= " " . reverse$_'
foo oof
bar rab

書記素クラスターでも動作するように拡張できます:

$ printf '%s\n' $'complique\u301' |
    perl -Mopen=locale -lpe '$_ .= " " . join "", reverse/\X/g'
compliqué éuqilpmoc

または zsh :

while IFS= read -r line; do
  print -r -- $line ${(j::)${(s::Oa)line}}
done

while read の使用は避けたいと思いますが、 zsh であっても、テキストを処理するためのループ (この特定のケースでは、組み込みコマンドしか使用されていないため、それほど悪くはありません)。

一般的には、一時ファイルを使用するのがおそらく最善の方法です。 zsh で 、あなたはそれを行うことができます:

(){paste -d ' ' $1 <(rev <$1)} =(print -l foo bar)

(ここで =(...) 一時ファイルの作成とクリーンアップを処理します)。

パイプと何らかの形式の tee に置き換える ing は、一般的なケースでのデッドロックのレシピです。デッドロック状況に関するいくつかのアプローチと詳細については、次の同様の質問を参照してください。

  • 別のコマンドの入力を分割し、結果を結合する
  • tee + cat:出力を数回使用し、結果を連結します

Linux
  1. パイプラインで`ping`からの出力の各ラインをすぐに処理しますか?

  2. エコーバックのないパスワードを取得するためのコマンドラインユーティリティ?

  3. Bashスクリプト:コマンド出力の各行を配列内の値に割り当てる方法は?

  1. コマンドへの引数としてテキストファイルの各行を解析する方法は?

  2. シェル コマンドの出力の最初の行を取得する

  3. コマンド出力に改行を追加する

  1. 実行時のコマンドの各出力のプレフィックス

  2. コマンド ライン:出力から部分文字列を抽出する

  3. Linux 'w' コマンドの出力で IDLE 列を読み取る方法は?