다음과 같은 파이프라인이 있습니다.
➜ echo ,cats,and,dogs, | sed -e 's/,[^,]*,[^,]*,/,,,/'
,,,dogs,
!!
"마지막 명령 실행" 또는 "마지막 인수 가져오기" 와 같은 명령을 실행할 수 있다는 것을 알고 있지만 "파이프에서 !:1
"를 수행할 수 있는 명령이 있는지 궁금합니다 .k
sed
따라서 이 예에서 일부 추가 출력을 유틸리티 에 파이프하려면 위 파이프라인을 실행한 직후에 다음과 같은 작업을 수행할 수 있습니다.
$ echo ,foo,bar,baz, | %:2
%:2
내가 알지 못하는 가상의 명령이 있을 수 있습니까 ? k
"파이프라인에서 첫 번째 명령 실행" 명령이 존재합니까?
답변1
역사적 확장은 터미널이 매우 느리고 제한적이었던 80년대(에서 소개)에 csh
엄청났습니다 . 하지만 문제는 눈에 보이는 것이 곧 얻는 것이 아니라는 점입니다. 너무 늦을 때까지(명령이 이미 시작됨) 확장되는 내용을 볼 수 없습니다(일부 쉘에서는 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') 또는 완전히 다른 것을 보낼 수도 있습니다. check Ctrl+V)를 사용하여 마지막 문자를 삽입합니다. 마지막 파이프 요소(포함 |
)에 명령을 내리고, 다시 누르면 이전 명령과 Alt+2Alt+Shift+P마지막 2개 파이프 요소에 대해 실행됩니다.
(z)
쉘 파서를 호출하여 명령줄을 단어로 분할합니다. 원하는 것을 찾은 |
다음 그 오른쪽에 있는 단어를 결합합니다.하나공간. 이는 가 |tr a b
될 것임을 의미 | tr a b
하지만 복잡한 여러 줄 구조를 사용하지 않는 한(예: sed 's/ /x/'
로 변경하지 않는 한) 명령의 의미에 영향을 주지 않아야 합니다.sed 's/ /x/'
새 위젯을 정의하고 싶지 않다면 뒤로 검색하고( Ctrl+Rwhat-if 모드를 사용하여, emacs
모드에서도 동일한 작업을 수행할 수 있음) 줄 끝까지 삭제하고 명령으로 돌아가는 것입니다. () 에 붙여넣습니다. 이는 기록 확장을 사용하는 것보다 여전히 빠르며 여전히 시각적입니다(자르려는 항목을 시각적으로 더 잘 선택할 수 있음).vi
|Ctrl+KDownCtrl+Y|
답변2
"파이프 뒤"가 아니라 "세 번째 공백 뒤"가 어떻게 도움이 될 수 있는지 잘 모르겠습니다.
$ echo ,cats,and,dogs, | sed -e 's/,[^,]*,[^,]*,/,,,/'
,,,dogs,
$ echo ,cat,and,mouse, | !:3-$
,,,mouse,
"파이프라인 뒤의" 솔루션:
$ echo ,cats,and,dogs, | sed -e 's/,[^,]*,[^,]*,/,,,/'
,,,dogs,
$ after_pipe="$(cut -d "|" -f 2- <<<"!!" )"
$ echo ,cat,and,mouse, | eval "$after_pipe"
$ ,,,mouse,
( cut
첫 번째 명령에 인용된 파이프 "|"가 있는 경우 더 나은 것이 필요합니다.)