複数のファイルに「切り取り」を適用してから結果を「貼り付け」する方法は?

複数のファイルに「切り取り」を適用してから結果を「貼り付け」する方法は?

私はこれを頻繁にします

paste <(cut -d, -f1 file1.csv) <(cut -d, -f1 file2.csv)

複数のファイルの場合、これは非常に退屈な作業です。

たとえば、ワイルドカードを使用してこのプロセスを自動化できますか?cut結果を保存できます。

typeset -A cut_results
for f in file*.csv; do
    cut_results[$f]="$(cut -d, -f1 $f)"
done

しかし、そこからどのように行くのかわかりません。

ベストアンサー1

特にワイルドカードを使用して自動化できます。e グローバル予選、 plus eval、しかし、ビューによくない参照するのは難しいです。

eval paste *.csv(e\''REPLY="<(cut -d, -f1 $REPLY)"'\')
  • その間の部分は、\'…\'各マッチングに対してグローバルに実行されるいくつかのコードです。REPLY一致するように設定された変数で行われ、修正が可能です。
  • globを解析するときに拡張しないように、コードを一重引用符で囲みました。
  • 一致する場合、コードはREPLY="<(cut -d, -f1 $REPLY)"文字列を生成します。コードの実行時に置き換えられた値に加えて、等号の後の部分が拡張されないように二重引用符が必要です。<(cut -d, -f1 file1.csv)file1.csveREPLY
  • 各ワイルドカードファイルは文字列に置き換えられます。

機能の複雑さを隠すことをお勧めします。最小限のテストを受けました。

function map {
  emulate -LR zsh
  local cmd pre
  cmd=()
  while [[ $# -ne 0 && $1 != "--" ]]; do
    cmd+=($1)
    shift
  done
  if ((!$#)); then
    echo >&2 "Usage: $0: COMMAND [ARGS...] -- PREPROCESSOR [ARGS...] -- FILES..."
    return 125
  fi
  shift
  while [[ $# -ne 0 && $1 != "--" ]]; do
    pre+="${(q)1} "
    shift
  done
  if ((!$#)); then
    echo >&2 "Usage: $0: COMMAND [ARGS...] -- PREPROCESSOR [ARGS...] -- FILES..."
    return 125
  fi
  shift
  eval "${(@q)cmd}" "<($pre${(@q)^@})"
}

使用例(構文は次のことを思い出させますzargs):

map paste -- cut -d, -f1 -- *.csv

おすすめ記事