매개변수를 신속하게 재정렬할 수 있는 쉘이 있습니까?

매개변수를 신속하게 재정렬할 수 있는 쉘이 있습니까?

저는 명령줄을 많이 사용하며 수년에 걸쳐 일상적인 드라이버 셸로 bash마이그레이션 했습니다 . zsh저는 보통 약간 맞춤화된 oh-my-zsh 환경을 사용하지만, 일부 시스템은 prezto를 사용하고 있는데 그 차이는 크지 않습니다.

제가 zsh에서 사용한 가장 효율적인 플러그인은 zsh-syntax-highlighting및 이며 , 최근에는 기록을 추출하는 데 history-substring-search매우 강력한 플러그인을 사용하고 있습니다 .fzf

이제 명령줄에서 제가 느끼는 가장 큰 문제점 중 하나는 명령 매개변수 재정렬입니다. 나는 종종 명령을 실행하려고 시도합니다

command very/long/filesystem/path/to/argumentA another/filesystem/or/network/path/argumentB

그리고 순서가 바뀌었다는 것을 깨달았습니다.

또 다른 일반적인 상황은 "수동 배포" 작업 흐름을 수행할 때입니다. 먼저 새 콘텐츠를 실제 콘텐츠와 비교합니다.

diff /opt/app/static/www/a.html /home/user/docs/dev/src/a.html
cp /home/user/docs/dev/src/a.html /opt/app/static/www/a.html

좋아요, 좋아요, 마지막 예(이것은 몇 단계로 구성되어 있습니다). 더 이상은 없을 것이라고 약속합니다. 완벽한 실제 사례가 바로 여기에 있습니다. 귀여운 인간 크기의 파일 목록부터 시작해 보겠습니다.

find /pool/backups -type f -print0 | xargs -0 ls -lh > filelisting

대화식으로 크기별로 정렬하고 일부를 선택하고 싶습니다.

sort -rhk5 filelisting | fzf -m > /these/are/the_chosen

좋습니다. 작동합니다! 아 하지만 난 필요해오직지금 경로를 지정하지만 다시 실행하고 싶지 않습니다 find.

cut -d ' ' -f 10 /these/are/the_chosen

ls -lh공백을 사용하는 데 문제가 있기 때문에 출력은 쓰레기입니다 . 하지만 나에게는 전략이 있습니다. 연속적인 공간을 추가하는 것입니다. tr -s공백 문자를 압축하도록 선택하겠습니다 . 여기에는 정규 표현식이 필요하지 않습니다. 그러나 tr표준 입력이 필요합니다.

cat /these/are/the_chosen | tr -s ' ' | cut -d ' ' -f 9- > filelist

이 시점에서 우리는 명령 내에서 매개변수를 잘라내고 붙여넣는 과정에서 어려움을 겪었습니다. 여기서 내 선택은 항상 어색한 선택 사이입니다. 긴 경로를 이동할 수 있거나 명령을 이동할 수 있습니다. 어느 것을 움직여도 복사하려면 마우스에 손을 뻗거나, 새 위치에 다시 입력해야 합니다. 나는 이길 수 없다. 명령줄을 사용하면 탐색조차 번거로울 수 있습니다. 특히 단어 건너뛰기를 위한 단축키가 없는 경우에는 더욱 그렇습니다.

마우스를 사용하여 쉘 프롬프트를 빠르게 이동할 수도 없습니다! (마우스 이벤트를 지원하는 쉘을 아는 사람이 있나요?) 그래서,이것제가 없애고 싶은 비효율성입니다. 괴물 파이프라인을 프로토타이핑할 때 쉘 객체(예: 유효한 경로 문자열)를 잡아서 왼쪽과 오른쪽으로 자유롭게 움직일 때 발생하는 마찰을 제거하고 싶습니다. 이 기능이 있으면 5번 스팸을 보내고 & 기호 왼쪽으로 경로를 푸시 cut하고 나머지 파이프라인을 유기적으로 구축할 수 있습니다.

라인 편집 기능이 부족한 것이 문제라고 생각합니다. 첫 번째 예에서는 처음 2개의 매개변수를 바꾸려고 합니다. cpto매개변수를 반대로 바꾸고 cp명령에 위임하기 위해 호출할 수 있는 간단한 셸 스크립트를 만들 수 있습니다. 하지만 나는 그렇게 하고 싶지 않으며 세 번째 예처럼 일반적으로 나에게 도움이 되지도 않습니다.

다음 플러그인을 사용하여 Vim에서 다양한 유형의 목록을 처리할 수 있는 것처럼 간단한 키 조합을 사용하여 입력한 인수의 순서를 바꾸고 싶습니다.샛길.

zsh용 플러그인이 있나요? 다른 쉘에 대한 플러그인이 있습니까?

그렇지 않다면 zsh를 구현하는 것이 얼마나 어려울까요? 나는 zsh-syntax-highlighting 플러그인이 매개변수 표시가 가능하다는 것을 증명했다고 생각합니다. 실제로 쉘은 기록에서 단일 인수를 얻는 방법을 알고 있습니다.https://stackoverflow.com/a/21439621/340947

이 문제점은 너무 심각하고 만연하여 기록의 마지막 항목을 가져오고 마지막 2개의 매개변수를 교체한 다음 실행하는 단축키에 바인딩하는 간단한 스크립트를 작성해야 했습니다. 그러나 이는 명령 실행을 커밋하는 대신 대화식으로 스왑을 수행할 수 있도록 라인 편집기를 사용하여 작동하는 것만큼 이상적이지 않습니다.

아마도 이것에 대한 개선 사항은 주입일 수 있지만 !:0 !:2 !:1(zsh는 나에게 맞게 자동 크기 조정됩니다), 이것 또한 많은 문제를 가지고 있습니다: (1) 잘못된 명령을 실행하지 않으면 작동하지 않습니다. 절반 이상은 잘못된 명령을 입력한 후 인수를 바꾸고 싶고 (2) 일반적으로 코드 조각에서 설명할 수 없는 일부 플래그를 사용합니다.

나는 또한 표시된 방법을 보았다.여기이것은 좋지만 여전히 매우 불만족스럽습니다. 왜냐하면 긴 경로에는 많은 반복 키 입력이 필요하고 Ctrl+Y 동작은 여러 항목을 저장하는 대신 가장 최근에 잘라낸 항목만 호출하기 때문입니다. 알아두면 좋지만 나에게는 거의 쓸모가 없습니다.

완전성을 위해 이제 전략은 적절한 키 조합을 사용하여 단어를 삭제하고, 더 짧은 명령을 삭제하여 재정렬하고, 커서 위치를 변경하고, 마우스를 사용하여 터미널 출력에서 ​​삭제된 매개변수를 복사한 다음 다시 붙여넣는 것입니다. 보통 사람들에게는 눈도 깜박이지 않지만, 할 때마다 약간 죽은 듯한 느낌이 듭니다. 컴퓨터가 이 작업을 수행하는 것이 얼마나 쉬운지, 그리고 제가 느끼는 불의에 대해 생각하는 것을 멈출 수 없기 때문입니다. . 마우스를 잡아야 해요.

답변1

에서는 zsh모든 위젯이 기본적으로 다음에서 실행됩니다 .성격일련의 숫자 + 문자로 정의된 단어 에 대해 모드 에서 작동하는 transpose-words기본 바인딩을 포함합니다 .Alt+Temacs$WORDCHARS

$WORDCHARShas 의 기본값 *?_-.[]~=/&;!#$%^(){}<>은 포함하므로 /전치에 적합해야 합니다.이러한 경로에 추가 문자가 포함되지 않는 한 괜찮습니다. :, @, ,...을 포함하거나 인용된 경로에서는 작동하지 않습니다 .

하지만 select-word-style프레임워크를 사용하여 정의를 변경할 수 있습니다.단어요청 시.

추가하는 경우:

autoload -U select-word-style
zle -N select-word-style
bindkey '\ez' select-word-style

그것을 당신에게 주고 ~/.zshrc누르면 Alt+Z다음과 같은 옵션이 나타납니다.

Word styles (hit return for more detail):
(b)ash (n)ormal (s)hell (w)hitespace (d)efault (q)uit
(B), (N), (S), (W) as above with subword matching
?

누른 후"자세한 내용은 다시 확인하세요.":

(b)ash:       Word characters are alphanumerics only
(n)ormal:     Word characters are alphanumerics plus $WORDCHARS
(s)hell:      Words are command arguments using shell syntax
(w)hitespace: Words are whitespace-delimited
(d)efault:    Use default, no special handling (usually same as `n')
(q)uit:       Quit without setting a new style

그래서 누르면 S당신에게 줄 것입니다바꾸어 놓다두 개의 쉘 단어(따라서 따옴표로 묶인 공백 또는 명령 대체를 포함하는 단어 포함...)를 사용합니다 Alt+T(또는 로 하나를 삭제 Ctrl+W하고 로 하나를 다시 이동하는 Alt+B등).

바라보다

info zsh select-word-style

zsh-doc자세한 내용은 (zsh 문서( Debian 및 그 파생 패키지)가 시스템에 설치되어 있다고 가정)입니다 .

당신을 위해 작성된 것처럼 보이는 섹션이 있으며, 이를 조정하여 transpose-words파일 이름이나 단어 사이 등에 커서가 있을 때마다 커서가 어떻게 작동할지 지정할 수 있습니다.

다음은 단어 컨텍스트 스타일을 사용하여 컨텍스트를 확장하는 몇 가지 예입니다.

   zstyle ':zle:*' word-context \
          "*/*" filename "[[:space:]]" whitespace
   zstyle ':zle:transpose-words:whitespace' word-style shell
   zstyle ':zle:transpose-words:filename' word-style normal
   zstyle ':zle:transpose-words:filename' word-chars ''

이는 커서가 단어 사이의 공백에 있는지 또는 파일 이름(이 경우 /가 포함된 단어)에 있는지에 따라 변형된 단어를 사용하는 두 가지 방법을 제공합니다. 공백의 경우 표준 쉘 규칙에 의해 정의된 전체 매개변수가 대체됩니다. 파일 이름에는 영숫자만 대체됩니다. 다른 곳에서는 단어가 기본 스타일을 사용하여 바뀌게 됩니다 :zle:transpose-words.

예를 들어 다음과 같습니다.

autoload -U select-word-style
zle -N select-word-style
bindkey '\ez' select-word-style
select-word-style normal
zstyle :zle:transpose-words word-style shell

transpose-words할 것이다껍데기항상 단어를 사용하고 다른 모든 단어 위젯은정상정의단어Alt+Z를 사용하여 변경할 수 있습니다 ( transpose-words.

답변2

나는 zsh의 vim 모드가 이전에 깨달은 것보다 조금 더 발전했다는 것을 알고 있습니다. a매개변수에 해당하는 텍스트 개체 가 있습니다 . 그래서 저는 이와 같은 순서를 입력함으로써 근육 기억을 활용할 수 있습니다 EscdaaBPiSpace. 그러나 8개의 키 입력이 이상적이지 않다는 점도 알 수 있습니다. 이 작업을 수행하려면 Vim에서 플러그인을 우아하게 구현해야 한다는 점을 고려하면 zsh 라인 편집기에서도 마찬가지입니다.

또한 zsh를 vim 모드로 전환하면 복사하기 쉬워야 하지만 기존 바인딩이 손상되었습니다. 때로는 쉘에 vim 바인딩을 두는 것이 정말 좋을 때도 있습니다. 그러나 나는 여전히 삽입 모드에 있는 쉘을 처리하는 것은 문제를 일으킬 가치가 없다는 입장을 갖고 있습니다.

답변3

나는 비슷한 문제에 여러 번 부딪혔고 깨끗한 해결책이 있다고 믿지 않습니다. 이 작업을 수행하려면 몇 가지 해킹을 수행할 수 있어야 합니다. 가장 해킹된 방법은 명령 앞에 echo를 붙인 다음 !:0을 삭제하여 명령을 실행하지 않고 기록에 직접 덤프하는 것입니다. 그러면 위의 솔루션이 작동합니다.

더 좋은 방법은 ZSH 버전의 readline(제 기억이 맞다면 zle)에 연결하는 것입니다. 이는 일반 readline보다 훨씬 강력하며 아마도 히스토리에 잘못된 명령을 쓰지 않고도 그 자리에서 작동할 수 있습니다. 시작점으로 이 줄을 자동으로 확장할 수 있는 기존 플러그인을 살펴보는 것이 좋습니다. 좋은 예는 다음 플러그인입니다.https://github.com/wazum/zsh-directory-dot-expansion(입력하면 확장됩니다 ...). ../..실제로 이 저장소를 보면 작성자의 원래 스크립트에서 1~2줄만 변경하면 이 논리에 대한 플러그인을 얻을 수 있을 것입니다.

zle사용자가 입력할 때 자동으로 확장되지는 않지만 특정 사용자 키 입력 순서( alt+T언급한 조합과 유사)에 반응합니다. 따라서 플러그인은 단순한 자동 확장보다는 탭 완성에 더 유사합니다.

답변4

경로와 관련하여 언급한 특정 사례를 해결하려면 복잡한 "스위치 시퀀스"를 사용할 필요가 없으며 검색 기록을 퍼징하기 위해 fzf와 같은 최신 경로 기록 관리가 필요합니다. Zsh Archwiki에서는 dirs를 언급해야 하며 이를 확인해야 합니다.

나는 종종 어떤 경로로 CD를 이동한 다음 현재 내가 있지 않은 경로 내에서 뭔가를 해야 한다는 것을 알게 되었습니다. 경로 기록 관리는 fzf와 마찬가지로 효율성을 향상시킵니다.

관련 정보