以下を出力するスクリプト 'myscript'があります。
abc
def
ghi
別のスクリプトでは、私は次のように呼びます。
declare RESULT=$(./myscript)
$RESULT
値を取得します
abc def ghi
結果を改行または '\ n'文字で保存して ' echo -e
'で出力できるようにする方法はありますか?
以下を出力するスクリプト 'myscript'があります。
abc
def
ghi
別のスクリプトでは、私は次のように呼びます。
declare RESULT=$(./myscript)
$RESULT
値を取得します
abc def ghi
結果を改行または '\ n'文字で保存して ' echo -e
'で出力できるようにする方法はありますか?
回答:
実際、RESULTには必要なものが含まれています。
echo "$RESULT"
あなたが示すものはあなたが得るものです:
echo $RESULT
コメントに記載されているように、違いは、(1)変数の二重引用符付きバージョン(echo "$RESULT"
)は、変数で表されているとおりの値の内部間隔(改行、タブ、複数の空白、およびすべて)を保持しますが、(2 )引用符で囲まれていないバージョン(echo $RESULT
)は、1つ以上の空白、タブ、改行の各シーケンスを1つのスペースに置き換えます。したがって、(1)は入力変数の形状を保持しますが、(2)単一のスペースで区切られた「単語」を持つ非常に長い出力の単一行を作成します(「単語」は空白以外の文字のシーケンスです。単語に英数字を使用しないでください)。
これのもう1つの落とし穴は、そのコマンド置換 — $()
—末尾の改行を削除することです。おそらく常に重要であるとは限りませんが、出力されたものを正確に保持したい場合は、別の行と引用符を使用する必要があります。
RESULTX="$(./myscript; echo x)"
RESULT="${RESULTX%x}"
これは、考えられるすべてのファイル名を処理する場合に特に重要です(誤ったファイルでの操作などの未定義の動作を回避するため)。
pwd=`pwd`; ls $pwd/$file
/
$PWD
特定の行に関心がある場合は、result-arrayを使用します。
declare RESULT=($(./myscript)) # (..) = array
echo "First line: ${RESULT[0]}"
echo "Second line: ${RESULT[1]}"
echo "N-th line: ${RESULT[N]}"
readarray
コマンド置換の代わりに、置換を使用して処理しますreadarray -t RESULT < <(./myscript>
。
@ l0b0の回答に加えて、スクリプトが出力する後続の改行をすべて保持し、スクリプトの戻りコードを確認する必要があるという状況がありました。そして、l0b0の答えの問題は、「エコーx」が$をリセットしていたということですか?ゼロに戻る...だから私はこの非常に狡猾な解決策を思いつくことができました:
RESULTX="$(./myscript; echo x$?)"
RETURNCODE=${RESULTX##*x}
RESULT="${RESULTX%x*}"
die ()
は、任意の終了コードとオプションでメッセージを受け入れる関数が必要なユースケースがあり、メッセージusage ()
を提供するために別の関数を使用したかったのですが、改行がつぶれてしまいました。それを回避します。
ここでほとんどの解決策を試した後、私が見つけた最も簡単なことは明らかでした-一時ファイルの使用。複数行の出力をどのように処理するかはわかりませんが、readを使用して1行ずつ処理できます。あなたが実際に行うことができない唯一のことについては、すべてを同じ変数に簡単に固定することですが、ほとんどの実際的な目的では、これは扱いがはるかに簡単です。
./myscript.sh > /tmp/foo
while read line ; do
echo 'whatever you want to do with $line'
done < /tmp/foo
要求されたアクションを実行するためのクイックハック:
result=""
./myscript.sh > /tmp/foo
while read line ; do
result="$result$line\n"
done < /tmp/foo
echo -e $result
これは余分な行を追加することに注意してください。あなたがそれに取り組むなら、あなたはそれをコードすることができます、私はただ怠惰です。
編集:このケースは完全にうまく機能しますが、これを読んでいる人は、whileループ内でstdinを簡単に押しつぶすことができるので、1行実行してstdinをクリアして終了するスクリプトを提供できることに注意してください。SSHのように私はそれを行うでしょうか?私は最近それを見ました、他のコード例はここにあります:https://unix.stackexchange.com/questions/24260/reading-lines-from-a-file-with-bash-for-vs-while
もう1回!今回は異なるファイルハンドルを使用します(stdin、stdout、stderrは0〜2なので、bashでは&3以上を使用できます)。
result=""
./test>/tmp/foo
while read line <&3; do
result="$result$line\n"
done 3</tmp/foo
echo -e $result
mktempを使用することもできますが、これは簡単なコード例です。mktempの使用法は次のようになります。
filenamevar=`mktemp /tmp/tempXXXXXX`
./test > $filenamevar
次に、実際のファイル名と同じように$ filenamevarを使用します。おそらくここで説明する必要はありませんが、誰かがコメントで不満を言っています。
bash
落とし穴を回避できません。
read
コマンド拡張を-u 3
ファイルディスクリプタ3から読み出すために
これはどうですか、それは変数に各行を読み取り、それを後で使用することができます!myscript出力がmyscript_outputというファイルにリダイレクトされると言う
awk '{while ( (getline var < "myscript_output") >0){print var;} close ("myscript_output");}'