指定されたインデックス/行番号で最後のコマンド出力を再利用します。

指定されたインデックス/行番号で最後のコマンド出力を再利用します。
ls

示す:

entry1
entry2
entry3

次のシェルコマンドで上記の出力(すべてのエントリではなくnなどの特定の行のエントリ)を再利用するにはどうすればよいですか?

それは次のとおりです。

vi $(!!)@3

以下を意味する必要があります。

vi entry3

答え1

出力を直接再利用することはできません。ビデオメモリにピクセルバンドルとして保存したり、端末エミュレータのメモリに保存したりすることもできますが、そこから再インポートする便利な方法はありません。できることは、コマンドを再実行して今回は出力をキャプチャすることです。それがまさにそのことです!!

zsh では、次を使用します。パラメータ拡張フラグ入れ子になった置換で選択した行を抽出します。あるいは、外部ユーティリティを使用して分割して簡単に入力できます。

vi "${${(f)$(!!)}[3]}"
vi "$(!! | awk NR==3)"

これはzshでも実際に二重引用符が必要な数少ない場合の1つです。それ以外の場合、コマンドの出力はスペースで区切られたコンポーネントに分割されます。スペースで区切られたコンポーネントが問題ない場合は、より短いコマンドを使用できます。

vi ${$(!!)[3]}

答え2

出力から特定の行を抽出する一般的な方法は、headコマンドtailを組み合わせることです。

LINE=3
ls | head -n $LINE | tail -n 1
  • lsこのコマンドは初期出力を生成します。
  • head -n $LINE$LINE元の出力の最初の行だけを保持し、
  • tail -n 1コマンド出力の最後の行だけが保持されますhead

最後に、与えられた位置の行だけが保持されます。

したがって、例を続行するには、この出力にを使用して編集する必要があるファイルの名前が含まれているとし、次の構文をvi使用してこの出力を使用できます。

vi $(ls | head -n $LINE | tail -n 1)
vi `ls | head -n $LINE | tail -n 1`

最初は読みやすさのために好まれます。 2番目は、古いシステムと互換性のある履歴バージョンです。

最後に注意すべき点は、初期コマンド(lsこの場合は単純なコマンド)の実行に時間がかかり、リソースを消費できることです。出力から数行を取得する必要がある場合は、躊躇せずに出力を変数またはファイルに保存して一度だけ実行します。

# Using a variable:
my_ls=$(ls)
vi $(echo "$my_ls" | head -n 3 | tail -n 1)
vi $(echo "$my_ls" | head -n 26 | tail -n 1)
vi $(echo "$my_ls" | head -n 1900 | tail -n 1)

# Using a file:
ls >./my_ls
vi $(cat ./my_ls | head -n 3 | tail -n 1)
vi $(cat ./my_ls | head -n 26 | tail -n 1)
vi $(cat ./my_ls | head -n 1900 | tail -n 1)

答え3

私はzshの経験はあまりありませんが、考えられるアプローチは次のとおりです。

$ p() { i=$1 && shift && a=("${(@f)$("$@")}") && echo "${a[$i]}" }
$ ls
entry1
entry2
entry3
$ echo $(p 3 !!)
echo $(p 3 ls)
entry3

バッシュの場合:

$ p() { i=$1 && shift && IFS=$'\n' a=($("$@")) && echo "${a[$((i-1))]}"; }

私はこれがかなり面倒な構文であり、エラーチェックがないことを認めます。

関連情報