これは実際にbrew search
しかし、単純化のために次のようにすると仮定します。
echo -e 'somedir\n\otherdir'
somedir
otherdir
otherdir
これを行わずにパラメータとして使用できますか?
ls $(echo -e 'somedir\n\otherdir |tail -n1)
otherdir
目標を明確にするために更新されました
より明確にしてsomedir
stdoutotherdir
に行くには、単に行うことができます。otherdir
出力をキャプチャして $()
からコマンドを実行しませんか?
私はこれが可能だと思いますが、それが可能だとは思わないかと思います。
答え1
以下を使用して、いつでもxargs
出力ストリームをパラメータリストに変換できます。
printf 'somedir\n\otherdir\n' |
tail -n1 |
xargs -rd '\n' ls -l --
-d '\n'
行にGNU実装が必要なので、ここでは引数が必要ですxargs
。
最後の行にスペース、引用符、バックスラッシュがない場合は省略できます。
-r
ls
入力が空であれば実行を避ける必要がある、やはりGNUから来ましたがxargs
現在は広くサポートされています(そしてPOSIX標準の次のバージョンに現れる予定です)。
コマンド置換を無効にするには、bash
いつでもコマンド出力行を配列に読み込み、配列の最後の要素からコマンドを実行できます。
readarray -t lines < <(printf 'somedir\notherdir\n')
if (( ${#lines[@]} > 0 )); then
ls -l -- "${line[@]: -1}"
fi
または以下を使用してくださいperl
。
printf 'somedir\notherdir\n' |
perl -lne 'exec qw(ls -l --), $_ if eof && $.'
コマンド置換を使用すると、すべての末尾の改行が削除されるため、空の入力と空の最後の行を直接区別することはできません。どちらの場合も、拡張を取得して空になります。
コマンドの代替使用の利点の1つは、出力の使用を決定する前にコマンドが成功した(終了状態に基づいて)確認できることです。
die() { [ "$#" -eq 0 ] || printf>&2 '%s\n' "$@"; exit 1; }
last_line=$(
set -o pipefail
cmd | tail -n 1
) || die "cmd failed"
ls -l -- "$last_line"
あるいは、grep
それを使用して出力が空でないことを確認することもできます。
if
last_line=$(
set -o pipefail
cmd |
tail -n 1 |
grep '^'
)
then
ls -l -- "$last_line"
else
echo>&2 "Either cmd failed or it didn't produce any output"
fi
grep '^'
行の先頭に一致します。したがって、出力に1つ以上の行が含まれている場合(空であるかどうかにかかわらず)、trueを返します。ただし、入力が改行で終わらないと、POSIX行の定義によって行と見なされず、grep
この場合、一部の実装が失敗したり、区切られていない行を削除したりする可能性があります。
答え2
文法$()
番号救う何もない。これは基本的に「このコマンドを実行し、出力を引数として使用する」という意味です。
あなたの使い方は正しい標準的な作業方法です。
(まだ機能している)以前のシェルでは、バックティック( `)は次のように動作します。
しかし、これは$()
現代的な方法であり、既存の方法が持っていたトリッキーな参照問題も多く解決します。
たとえば、ほぼどこでも使用できます。
echo "The current time is: $(date)"
The current time is: Tue Nov 21 22:57:41 EST 2023