前のコマンドの出力を次のコマンドに渡します。

前のコマンドの出力を次のコマンドに渡します。

以下に、最終出力をソートされたファイルとして生成する2つのforループがありますが、1つのforループにマージしたいと思います。

for i in *.txt; do
    cut -f 5,10 $i >$i.txt.out
done

###sorting

for i in *.txt.out; do
    sort -k1,1 $i >$i.sort
done

パイプを使用して最初のforループの出力をリダイレクトして、2つのループを1つにマージしてみました。この投稿の方法の1つを試しました(前のコマンドの出力を次のコマンドの引数に渡します。)しかし、望ましい結果を得ることはできません。

for i in *.txt; do
    cut -f 5,10 $i >$i.txt.out | xargs -I{} sort -k1,1  {} >$i.sort
done

どんな提案がありますか?

ありがとう

ロン

ベストアンサー1

for name in *.txt; do
    cut -f 5,10 -- "$name" | sort -k 1,1 >"$name.sort"
done

これは、中間ファイルの使用を排除しながら、2つの初期ループの効果を組み合わせる。

私はいくつかの小さな修正をしました:

  • すべての変数の拡張を意味します。いつ二重引用符が必要ですか?
  • ループ変数にはより良い名前を使用してください。
  • ファイル名がダッシュで始まる場合は、cutコマンドから変数を分離して--オプションの終わりを示します。$name

上記のコマンドsort -k 1,1 -o "$name.sort"の代わりにこのコマンドを使用して、ユーティリティにシェルの代わりに出力ファイルを生成させることもできます(微妙な違い)。sortsort


このxargsユーティリティは頻繁に使用されます。変えるループ:

printf '%s\n' *.txt | xargs -I {} sh -c 'cut -f 5,10 -- "$1" | sort -k 1,1 >"$1.sort"' sh "{}"

...しかし、ここでは状況がより複雑になります(上記のコマンドは改行文字を含むファイル名に問題があります)。

注文

cut -f 5,10 $i >$i.txt.out | xargs -I{} sort -k1,1  {} >$i.sort

cut出力を実行し$i.txt.out(拡張$i)に保存します。xargs出力はファイルcutにリダイレクトされるため、コマンドは入力されません。出力をリダイレクトしていない場合は、次を使用しますcutxargssortコンテンツファイル名の代わりにファイル名が引数として渡されます。これはあなたが望むものではありません。 (あなたはcutasの出力を渡したいと思います。データ入力するsort)。

おすすめ記事