항목 \0
이 \n
. 내장된 파서는 fc 123
줄 바꿈을 유지하는 편집기가 열리므로 여러 줄 항목을 깔끔하게 처리합니다. 그러나 fc -l 123
(편집기를 시작하지 않고 표준 출력으로 인쇄) 개행 문자를 해당 문자로 변환합니다 \\n
. 이는 해당 리터럴을 포함하는 기록의 모든 명령이 \n
개행 문자와 구별될 수 없음을 의미합니다(예: printf "\n"
awk 호출에서).
fc
zsh 또는 zsh의 내장 기능을 사용하여 history
변경되지 않은 기록 항목을 얻는 방법이 있습니까 ? 히스토리 파일 파서를 작성하는 작업을 피하려고 합니다. 참고로 fish에는 history -z
이런 사용 사례가 있습니다.
(보너스: bash 기록을 분석하기 위해 동일한 작업을 수행하고 싶습니다. fc
zsh와 다르게 동작하는 것 같습니다.)
답변1
사용history
가변 합계매개변수 확장(포함할 수 있음(연관) 배열 인덱스) 특성.
예를 들어, 원래 해당 항목 fc -l 123 123
은 입니다 $history[123]
. 배열의 기록 요소 범위를 얻으려면 를 사용할 수 있습니다 ${(v)history[(I)<123-456>]}
. 문자열에서 기록 요소의 null로 구분된 목록을 얻으려면 를 사용할 수 있습니다 ${(vpj[\0])history[(I)<123-456>]}
. (그러나 기록 요소는 null 바이트를 포함할 수 있으며 null 바이트를 전달할 수 없습니다. 섹션을 외부 명령에 추가하므로 특별히 유용하지는 않습니다)
도착하다인쇄NUL로 구분된 경우 백슬래시 확장을 비활성화하기 위해 , 를 print -N
함께 사용할 수도 있습니다. 따라서 일치하는 항목이 없으면 아무것도 인쇄되지 않습니다.-r
-C1
print -rNC1 -- ${(v)history[(I)<123-456>]} | fzf --read0
또는:
print -rNC1 -- $history | fzf --read0
역사를 모두 가져가세요.
답변2
의 경우 bash
입력한 명령의 두 번째 및 후속 줄이 공백, 숫자 및 최소 2개의 공백으로 시작하지 않는다고 가정하면 다음을 수행할 수 있습니다.
HISTTIMEFORMAT= history | LC_ALL=C gawk -v RS='\n *[0-9]+ ' -v ORS='\0' '
NR==1 {sub(/^ *[0-9]+ /, "")}
{print}'
기록 출력을 변환하려면(타임스탬프 제거) 다음과 같이 하십시오.
123 cmd
124 echo 'multiline
command'
125 ...
도착하다:
cmd<NUL>echo 'multiline
command'<NUL>...<NUL>