最後だけでなく、すべてのコマンドからの出力をファイルにリダイレクトする


11

echoを使用してファイルにヘッダーを追加し、コマンドを使用して残りのファイルを作成します。つまり、2つの別々のコマンドを使用します。

リダイレクトを使用して、両方のコマンドの出力をファイルに書き込むにはどうすればよいですか?

私はもう試した

echo "header line" | cut -c 1-5 input_file > output_file

echo "header line"; cut -c 1-5 input_file > output_file

これは、cutコマンドからの出力のみをリダイレクトします。

次のコマンドは機能しますが、不便に感じられます。

echo "header line" > output_file; cut -c 1-5 input_file >> output_file

私の問題を解決する賢い方法は何ですか?

回答:


11

ここでの問題はLinuxリダイレクトの問題ではありません。むしろ、それはパイプラインがどのように機能するかについての根本的な誤解です。カットだけが実際にstdoutに出力されるため、ここでのリダイレクトは機能しません。echoコマンドのstdoutは、cutのstdinにパイプされています(ファイルが指定されているため、この場合は使用されません)。

echo "header line" > output_file && cut -c 1-5 input_file >> output_file

私はあなたを置き換え(すべての無粋あなたが望むものではなく、;&&ヘッダが正常に書き込まれている場合、カットコマンドのみが実行されるように、あなたはoutput_fileのに作成する権限や書き込みを持っていない場合は、この方法は、それが実行されません)。

すべてをサブシェルで実行することもできます。

(echo "header line"; cut -c 1-5 input_file) > output_file

しかし、これを行うことには実際の利点はなく、より複雑な例では、サブシェルのスコープがよくわからない場合に問題が発生する可能性があります。

カットしてstdinをstdoutに渡したい場合は、次のようにしてみてください。

echo "header line" | cut -c 1-5 - input_file

(ダッシュはstdinの一般的なショートカットです)

ただし、これによりstdinでカット操作も実行されます(結果として、「ヘッダー」のヘッダー行が生成されます)。これがあなたが欲しいものであるかどうかは、質問からはわかりません。


13

あなたが探しているのは:

{ echo "header line"; cut -c 1-5 input_file; } > output_file
  • コマンドはサブシェルではなく現在のシェルで実行されるため、この構文には副作用がありません。
  • output_fileに移動するコマンドには明確な区切りがあります
  • それはあなたがそれをそのように書き直すことができるのでうまくスケーリングします:

{
  echo "header line"
  cut -c 1-5 input_file
  ... # insert new commands here
} > output_file

エラー出力を同じファイルに出力する場合は、最後の行を次のように変更できます。

} > output_file 2>&1

そのヒントを思い出させてくれたOlivier Dulacに感謝します。

ブロック内の一部の出力を画面に表示する場合は、次の構文を使用できます。

{
  echo "header line"
  echo "this line doesn't go to output_file" > /dev/tty
  cut -c 1-5 input_file
} > output_file

+1:何がどこにリダイレクトされるかが明確になり、明確に識別されます。:(エラーMSGを含む)リダイレクトすべてに{ .... } > some_file 2>&1(。にないクロバー「クロバー」some_fileますが、それに追加する代わりに、単に変更>>>{ ... } >> some_file 2>&1
オリヴィエ・デュラック

4

答えを締めくくるために、execがあります。

exec > output_file
echo "header line"
cut -c 1-5 input_file

1:(物事が混乱を取得し始めると^^、それほどコマンドラインで)スクリプトではこれを使用することは非常に一般的です
オリヴィエ・デュラック

誰かがこのソリューションについて詳しく説明できますか?私はそれが何をしているのかを見ることができますが、私はこの文脈で「exec」を理解していません。また、スクリプトの残りの部分に通常の標準出力が必要な場合は、もう一度オフにする必要があるようです。
Joe

1
コマンドなしでスクリプトでexecを使用すると、現在のシェルと将来のすべての子に影響するexecでI / Oリダイレクトを実行できます。
2013年

ありがとう。今まで見たことがない。とても重宝すると思います。
Joe
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.