如何在管道中重新執行第 k 個命令?
我有以下管道:
➜ echo ,cats,and,dogs, | sed -e 's/,[^,]*,[^,]*,/,,,/' ,,,dogs,
我知道我可以執行一個命令,比如
!!
“執行最後一個命令”或!:1
“獲取最後一個參數”,但我想知道是否有一些可以執行的命令讓我“k
從管道”因此,在此範例中,如果我想將其他一些輸出通過管道傳輸到
sed
實用程序中,我可以在執行上述管道後立即執行以下操作:$ echo ,foo,bar,baz, | %:2
%:2
我不知道的一些可能是虛構的命令在哪裡,“在管道中執行第k
一個命令”這個命令是否存在?
在 80 年代(由 引入時
csh
)歷史擴展非常好,當時終端非常緩慢且有限。但問題是它們不是所見即所得的。在為時已晚(命令已經啟動)之前,您看不到它擴展的內容(儘管某些 shell 允許在按 Enter 之前執行擴展)。在這裡,我將創建一個在游標處插入最後一個管道元素的小元件。使用
zsh
(將其添加到~/.zshrc
):last-pipe-elements() { emulate -L zsh if [[ $WIDGET = $LASTWIDGET ]]; then # Invoking the widget several times retrieves pipeline # elements for older command lines ((last_pipe_elements_iteration++)) LBUFFER=$last_pipe_elements_saved_LBUFFER else last_pipe_elements_iteration=1 fi last_pipe_elements_saved_LBUFFER=$LBUFFER local -a words words=(${(z)${history[@]}[last_pipe_elements_iteration]}) local nth_pipe=${words[(In:NUMERIC:)\|]} ((nth_pipe)) || return LBUFFER+=${(j: :)words[nth_pipe,-1]} } zle -N last-pipe-elements bindkey '\eP' last-pipe-elements
這樣,您輸入
Alt+Shift+P
(這裡假設發送 ESC 和P
字元序列,您可能需要針對可能發送\xd0
($'\MP'
) 甚至\xf0
($’\Mp’) 或完全不同的東西的終端進行調整,檢查Ctrl+V
)以插入最後一個命令的最後一個管道元素(包括|
),對於之前的命令再次按下它,並Alt+2``Alt+Shift+P
用於最後 2 個管道元素。
(z)
呼叫 shell 解析器將命令行拆分為單詞。我們找到我們想要的,然後用一個空格|
連接右邊的單詞。這意味著它將成為,但只要您不使用複雜的多行結構(例如不會更改為),那不應該影響命令的含義。|tr a b``| tr a b``sed 's/ /x/'``sed 's/ /x/'
如果您不想定義新的小元件,您可以做的另一件事是向後搜尋(使用
Ctrl+R
假設emacs
模式,儘管您可以在vi
模式中執行等效操作)搜尋 previous|
,刪除到行尾Ctrl+K
並返回您的命令 (Down
) 將其粘貼到Ctrl+Y
. 這仍然比使用歷史擴展更快,並且仍然是可視的(您可以更好地直覺地選擇|
要從中刪除的內容)。