최소한의 예:
man git | cat
실제 예:
man git | grep --color=always -C 3 "pathspec"
--pager="cat"
FWIW, 다양한 호출기를 사용하고 다양한 호출기에 파이핑을 시도했습니다 . 저도 vimcat
같은 방법으로 사용해봤는데 아쉽게도얼어붙었어. 나는 심지어 unbuffered
아무 소용이 없었습니다.
-T
어쩌면 or 을 사용하는 것이 가능할 수도 있지만 {g,n,t}roff
어떻게 해야 할지 잘 모르겠습니다. less
/ vim
etc로 파이프해서 stdout으로 전달할 수 있는 방법이 있나요?서식 지정(색상 등)그리고페이지 매김 없음?
편집하다:아래 Stéphane의 도움 덕분에 이제 일치하는 모든 매뉴얼 페이지를 쉽게 검색하고 강조 표시할 수 있는 좋은 방법을 갖게 되었습니다. 이것은 나에게 게임 체인저입니다. 고마워요, 스테판!
관심이 있으신 분들을 위해 스크립트의 주요 부분은 다음과 같습니다. (의심할 바 없이 개선될 수 있습니다. 피드백은 언제나 환영합니다.)
편집하다:이제 Stéphane의 추가 피드백을 통합했습니다. 엄청난 진전!
편집하다:Ubuntu 20.04.4 LTS 및 macOS 12.6에서 작동하도록 이 솔루션을 더욱 개선했습니다.파이프로ul
.
#!/bin/bash
arg_search="$1"
typeset -A seen=()
while IFS= read -ru3 filename; do
if (( ! seen[\$filename]++ )); then
# 'man -awK' sometimes returns bogus results due to searching through
# everything, including comments in the man source file, so filter
# these out. Note that this creates a secondary problem: legitimate
# results may get filtered out when the search term is two or more
# words spanning across lines. This can be solved with a multiline
# regex using `pcre2grep -M 'search\s+term`, but this is perhaps
# growing beyond the scope of things here.
{ man --no-hyphenation --no-justification --regex -- "$filename" | \
grep -iqE -- "$arg_search"; } || continue
# Print filename. Fill terminal width with highlighted background color.
filename_bar="$(printf '%s\t' "$filename" | expand -t $(tput cols))"
printf '\e[1;103;30m%s\e[0m\n' "$filename_bar"
# Per Stéphane's feedback, here's a cleaner version of the same for zsh:
# psvar=${(mr[COLUMNS])filename} print -P '%K{yellow}%F{black}%1v%k%f'
MAN_KEEP_FORMATTING=1 man \
--no-hyphenation --no-justification --regex -- "$filename" | \
ul | \
grep -iE --color=always -- "$arg_search"
fi
# 'unbuffer' seems to be required for macOS in order to unbuffer the output,
# as 'stdbuf -oL -eL' doesn't seem to work. Install on macOS using
# 'brew install expect' [sic], which contains unbuffer. This otherwise
# doesn't hurt anything on Ubuntu 20.04.4 LTS. Unbuffering the output of
# 'man -awK' is important because it can take a long time to run.
done 3< <(unbuffer man -awK --regex -- "${arg_search}")
답변1
노력하다:
GROFF_SGR=1 man -P 'grep --color=always -C 3 pathspec' git
로 파이프하는 경우 (적어도 Debian 기반 시스템에서는) 전통적인 문자열 대신 굵은/밑줄에 ANSI SGR 이스케이프 시퀀스(예: )를 사용하여 grep을 어렵게 만들 수 있습니다 grep
. 바라보다GROFF_SGR=1
\e[1mBOLD\e[m
B\bBO\bOL\bLD\bD
Grep: 매뉴얼 페이지에서 제목에 있는 단어를 검색할 때 예기치 않은 결과가 발생함더 알아보기.
호출기(여기)는 grep
표준 출력이 터미널로 갈 때만 실행된다는 점에 유의하세요. man
이와 같은 명령을 파이핑하면 less
명령 grep
과 형식이 비활성화됩니다.
MAN_KEEP_FORMATTING
제가 대답했을 때 테스트에서 SGR을 비활성화하는 데 사용된 설정이 있었습니다.Grep: 매뉴얼 페이지에서 제목에 있는 단어를 검색할 때 예기치 않은 결과가 발생함그때는 그랬지만 더 이상은 그렇지 않은 것 같습니다(적어도 Ubuntu 20.04에서는 그렇지 않습니다).
따라서 호출기를 사용하려면 다음을 수행하십시오.
GROFF_SGR=1 MAN_KEEP_FORMATTING=1 man git |
grep --color=always -C 3 pathspec | less -R
에 의해 시작되지 는 않지만 man
.less
-P
grep
pager
예를 들어 다음과 같습니다 zsh
.
mangrep()
GROFF_SGR=1 CODE="
grep --color=always -C3 ${(j[ ])${(qq)@[2,-1]}} | pager
" man -P 'sh -c "eval \"$CODE\""' $1
예를 들면 다음과 같습니다.
mangrep git -i pathspecs
귀하가 pager
에 less
의해 시작되었으므로 다음과 같이 man
설정된 LESS*
환경 변수를 상속합니다 man
.
LESS=-ix8RmPm Manual page git(1) ?ltline %lt?L/%L.:byte %bB?s/%s..?e (END):?pB %pB\%.. (press h for help or q to quit)$PM Manual page git(1) ?ltline %lt?L/%L.:byte %bB?s/%s..?e (END):?pB %pB\%.. (press h for help or q to quit)$
LESSCHARSET=utf-8
bash(4.4+)에 해당하는 내용은 다음과 같습니다.
mangrep() {
local page=$1 IFS=' '
shift
GROFF_SGR=1 CODE="
grep --color=always -C3 ${*@Q} | pager
" man -P 'bash -c "eval \"$CODE\""' ${page:+"$page"}
}
( 공백으로 연결하는 대신 "$*"
및 (sh 호환 인용) 대신 (디코딩 필요 )을 사용하고 배열 범위와 결합할 수 없으므로 첫 번째 인수를 사용하고 저장합니다 .)IFS=' '
j[ ]
@Q
bash
(qq)
shift
$page
@Q
허용되는 옵션 man
( 에서 ):zsh
mangrep() {
local page=$@[(i)[^-]*]
GROFF_SGR=1 CODE="
grep --color=always -C3 ${(j[ ])${(qq)@[page+1,-1]}} | pager
" man -P 'sh -c "eval \"$CODE\""' "$@[1,page]"
}
예를 들면 다음과 같습니다.
mangrep -a printf -i precision
모든 매뉴얼 페이지(전달됨)에서 대소문자를 구분하지 않음(전달됨)을 찾으십시오 precision
.i
-i
grep
a
printf
-a
man
함수 대신 스크립트로 만드세요.
#! /bin/zsh -
page=$@[(i)[^-]*]
GROFF_SGR=1 CODE="
grep --color=always -C3 ${(j[ ])${(qq)@[page+1,-1]}} | pager
" exec man -P 'sh -c "eval \"$CODE\""' "$@[1,page]"
그러면 zsh
.
편집 내용에 게시한 코드에 대한 일부 의견:
[...]
man -w -a -K "$arg_search" | \
이어야 합니다 man -w -a -K -- "$arg_search"
. 그렇지 않으면 로 시작하는 항목을 검색할 수 없습니다 ( 해결 방법과 같은 항목을 -
사용하는 것 제외 ).arg_search='[-]-foo'
stdbuf -oL -eL uniq | \
uniq
연속된 중복 항목만 제거
xargs -d $'\n' -n 1 -I {} env bash -c "
-I
그리고 -n 1
그것은 중복됩니다. 또한 bash
인라인 스크립트는 각 매개변수에 대해 호출하지 않고도 여러 매개변수를 사용할 수 있습니다 bash
.
$( cat <<EOF
인용되지 않은 것처럼 EOF
확장은 여기 문서에서 다음과 같이 구현됩니다.쉘 코드토론. 이는 나쁜 습관이며 전형적인 코드 주입 취약점입니다. 외부 데이터는 매개변수나 환경 변수로 전달되어야 합니다.
filename='{}'
xargs
마찬가지로 (by ) 의 확장은 {}
쉘 코드에서 끝납니다.
filename_length="\${#filename}" terminal_width="$(tput cols)" delta_length="\$(("\$terminal_width" - "\$filename_length"))" # Print filename, and fill width with highlighted background color. padding="\$(seq -s' ' "\$(("\$delta_length" + 1))" | \ tr -d '[:digit:]')" printf '\e[1;103;30m%s\e[0m' "\$filename\$padding"
꽤 복잡합니다. 나는 zsh
다음을 사용합니다.
psvar=${(mr[COLUMNS])filename} print -P '%K{yellow}%F{black}%1v%k%f'
다른 쉘의 경우 다음을 사용하여 문자열을 오른쪽 채울 수도 있습니다.
printf '%s\t' "$string" | expand -t "$(tput cols)"
최소한 BSD 및 zsh의 r
라이트 패딩 확장 플래그와 마찬가지로 m
플래그와 함께 사용하면 각 문자의 표시 너비가 고려됩니다(그러나 이스케이프 시퀀스는 지원되지 않으므로 로 전송되는 텍스트에 색상 시퀀스가 포함되어서는 안 됩니다 expand
).
GROFF_SGR=1 man --no-hyphenation --no-justification \ "\$filename" | grep --color=always "$arg_search"
[...]
나는 당신이 MAN_KEEP_FORMATTING
그것을 정의했다고 가정합니까? 이것이 없으면 파이핑할 때 형식이 손실됩니다 grep
.
또한 man -K
고정 문자열 검색 및 확장 정규식 검색에 대한 및 사용은 --regex
두 경우 모두 대소문자를 구분하지 않으므로 검색 논리를 일치시키려면 옵션 과 추가 -i
및 --regex
추가 man
가 -E
필요 grep
합니다 .-F
grep
따라서 여기서는 다음과 같이 하는 것이 좋습니다.
#! /bin/zsh -
ere=${1-GROFF_NO_SGR}
typeset -A seen=()
while IFS= read -ru3 filename; do
if (( ! seen[\$filename]++ )); then
psvar=${(mr[COLUMNS])filename} print -P '%K{yellow}%F{black}%1v%k%f'
GROFF_SGR=1 MAN_KEEP_FORMATTING=1 man --no-hyphenation \
--no-justification -l "$filename" |
grep -iF --color=always -C4 -- "$ere"
fi
done 3< <(man -awK -- "$ere")
답변2
내가 찾은 유일한 방법은 두 가지를 모두 사용하는 것입니다.맥OS 12.6 그리고 우분투 20.04.4 LTS매우 간단하게 다음과 같습니다.
MAN_KEEP_FORMATTING=1 man git | ul
(Stéphane Chazelas의 답변은 훨씬 더 자세하고 많은 시간과 전문 지식을 제공해 주셔서 감사합니다.)