マルチプロセス交換と組み合わせる

マルチプロセス交換と組み合わせる

次のようなことを試したとしましょう。

$ paste ../data/file-{A,B,C}.dat

そして、貼り付ける前に各ファイルを並べ替えたいことを認識してください(数字の並べ替えを想定)。次に、プロセス置換を使用して次のように作成する必要があります。

$ paste <(sort -n ../data/file-A.dat) \
        <(sort -n ../data/file-B.dat) \
        <(sort -n ../data/file-C.dat)

ここでは多くの反復を見ることができますが、これは良くありません。各プロセス置換は互いに分離されているため、複数のプロセス置換にまたがる中括弧拡張またはパス名拡張(ワイルドカード文字)は使用できません。

sort -nこれを簡潔な方法で作成し(例えば、別々に提供する)、完全な../data/file-{A,B,C}.datコマンドラインを作成するためのツールはありますか?

答え1

次のことができます。

eval paste '<(sort -n ../data/file-'{A,B,C}'.dat)'

または関数で自動化

sort_paste() {
  local n i cmd
  n=1 cmd=paste
  for i do
    cmd="$cmd <(sort -n -- \"\${$n}\")"
    n=$(($n + 1))
  done
  eval "$cmd"
}
sort_paste  ../data/file-{A,B,C}.dat

(一部の実装ではにksh変更する必要があります)localtypeset

任意のコマンドを受け入れ、eval正しく使用すると安全であることを証明するには、次の手順を実行します。

xproc() {
  local n i cmd stage stage1 stage2 stage3
  cmd= xcmd= stage=1 n=1
  stage1='cmd="$cmd \"\${$n}\""'
  stage2='xcmd="$xcmd \"\${$n}\""'
  stage3='cmd="$cmd <($xcmd \"\${$n}\")"'
  for i do
    if [ -z "$i" ] && [ "$stage" -le 3 ]; then
      stage=$(($stage + 1))
    else
      eval 'eval "$stage'"$stage\""
    fi
    n=$(($n + 1))
  done
  eval "$cmd"
}

xproc paste '' sort -n -- '' ../data/file-{A,B,C}/dat

答え2

よりここeval使用することが危険である場合もある理由。ご存知のように、これは非常に強力なツールしかし、同時に大きなダメージをもたらす

次のスクリプトは目的の操作を安全に実行します。

sort_ps () 
{ 
    local cmd="$1" p=()
    shift;
    for f in "$@"; do
        p+=(<(sort -n "$f"));
    done
    "$cmd" "${p[@]}"
}

編集者:Chazerasさんは正しいです。sort_ps paste file1.txt file2.txt file2.txt ... fileN.txt今すぐ使用できるようにソリューションを修正しました。私の答えを見直してくれたStephenに感謝します。

出力例:

rany$ sort_ps sprunge foo1.txt foo.txt 
http://sprunge.us/EBZf?/dev/fd/62
http://sprunge.us/TQGC?/dev/fd/62

関連情報