"\n" 대신 "\0" 문자로 구분된 zsh 기록 내보내기

"\n" 대신 "\0" 문자로 구분된 zsh 기록 내보내기

항목 \0\n. 내장된 파서는 fc 123줄 바꿈을 유지하는 편집기가 열리므로 여러 줄 항목을 깔끔하게 처리합니다. 그러나 fc -l 123(편집기를 시작하지 않고 표준 출력으로 인쇄) 개행 문자를 해당 문자로 변환합니다 \\n. 이는 해당 리터럴을 포함하는 기록의 모든 명령이 \n개행 문자와 구별될 수 없음을 의미합니다(예: printf "\n"awk 호출에서).

fczsh 또는 zsh의 내장 기능을 사용하여 history변경되지 않은 기록 항목을 얻는 방법이 있습니까 ? 히스토리 파일 파서를 작성하는 작업을 피하려고 합니다. 참고로 fish에는 history -z이런 사용 사례가 있습니다.

(보너스: bash 기록을 분석하기 위해 동일한 작업을 수행하고 싶습니다. fczsh와 다르게 동작하는 것 같습니다.)

답변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>

관련 정보