파이프라인에서 kth 명령을 어떻게 다시 실행하나요?

파이프라인에서 kth 명령을 어떻게 다시 실행하나요?

다음과 같은 파이프라인이 있습니다.

➜  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첫 번째 명령에 인용된 파이프 "|"가 있는 경우 더 나은 것이 필요합니다.)

관련 정보