Chociaż prawdą jest, że niektóre wbudowane powłoki mogą mieć skąpe wyświetlanie w kompletnym podręczniku - szczególnie dla tych bash
specyficznych wbudowanych, których prawdopodobnie używasz tylko w systemie GNU (ludzie GNU z reguły nie wierzą w man
i wolą własne info
strony) - zdecydowana większość narzędzi POSIX - wbudowane powłoki lub inne - są bardzo dobrze reprezentowane w POSIX Programmer's Guide.
Oto fragment z dołu mojego man sh
(który prawdopodobnie ma około 20 stron ...)
Wszystkie te istnieją, a inne nie wymienione, takie jak set
, read
, break
... dobrze, nie trzeba ich wszystkich wymienić. Ale zwróć uwagę (1P)
na prawy dolny róg - oznacza serię instrukcji POSIX kategorii 1 - to man
strony, o których mówię.
Być może wystarczy zainstalować pakiet? To wygląda obiecująco dla systemu Debian. Chociaż help
jest przydatny, jeśli możesz go znaleźć, zdecydowanie powinieneś dostać tę POSIX Programmer's Guide
serię. To może być bardzo pomocne. I jego strony składowe są bardzo szczegółowe.
Poza tym wbudowane powłoki są prawie zawsze wymienione w konkretnej części podręcznika powłoki. zsh
, na przykład ma całą osobną man
stronę do tego - (myślę, że wynosi 8 lub 9 osobnych zsh
stron - w tym zshall
która jest ogromna).
Możesz grep
man
oczywiście:
man bash 2>/dev/null |
grep '^[[:blank:]]*read [^`]*[-[]' -A14
read [-ers] [-a aname] [-d delim] [-i text] [-n
nchars] [-N nchars] [-p prompt] [-t timeout] [-u
fd] [name ...]
One line is read from the standard input, or
from the file descriptor fd supplied as an
argument to the -u option, and the first
word is assigned to the first name, the sec‐
ond word to the second name, and so on, with
leftover words and their intervening separa‐
tors assigned to the last name. If there
are fewer words read from the input stream
than names, the remaining names are assigned
empty values. The characters in IFS are
used to split the line into words using the
same rules the shell uses for expansion
... co jest bardzo podobne do tego, co robiłem podczas przeszukiwania man
strony powłoki . Ale w większości przypadków help
jest całkiem dobry bash
.
sed
Ostatnio pracowałem nad skryptem do obsługi tego rodzaju rzeczy. W ten sposób złapałem sekcję na powyższym obrazku. Jest jeszcze dłuższy niż lubię, ale poprawia się - i może być całkiem przydatny. W bieżącej iteracji całkiem niezawodnie wyodrębni kontekstową sekcję tekstu dopasowaną do nagłówka sekcji lub podsekcji na podstawie wzorca [a] podanego w wierszu poleceń. Koloruje wydruki i drukuje na standardowym ekranie.
Działa poprzez ocenę poziomów wcięć. Niepuste linie wejściowe są na ogół ignorowane, ale gdy napotka pustą linię, zaczyna zwracać uwagę. Stamtąd zbiera linie, dopóki nie zweryfikuje, że bieżąca sekwencja zdecydowanie wcina się dalej niż pierwsza linia, zanim pojawi się kolejna pusta linia, albo upuści wątek i czeka na następny pusty wiersz. Jeśli test się powiedzie, próbuje dopasować linię wiodącą do argumentów wiersza poleceń.
Oznacza to, że mecz wzorca pasują:
heading
match ...
...
...
text...
..i..
match
text
..ale nie..
heading
match
match
notmatch
..lub..
text
match
match
text
more text
Jeśli można dopasować, rozpocznie się drukowanie. Spowoduje to usunięcie wiodących odstępów dopasowanej linii ze wszystkich drukowanych linii - więc bez względu na poziom wcięcia, który znalazł, linia na nim drukuje go tak, jakby znajdowała się na górze. Będzie kontynuował drukowanie, dopóki nie napotka innej linii na poziomie równym lub mniejszym niż wcięcie niż dopasowana linia - więc całe sekcje są chwytane tylko z dopasowaniem nagłówka, w tym wszystkie / wszystkie podsekcje, akapity, które mogą zawierać.
Zasadniczo, jeśli poprosisz go o dopasowanie wzoru, zrobi to tylko w odniesieniu do jakiegoś nagłówka tematu i pokoloruje i wydrukuje cały tekst, który znajdzie w sekcji, której nagłówek odpowiada. Nic nie jest zapisywane, ponieważ robi to, z wyjątkiem wcięcia w pierwszym wierszu - dzięki czemu może być bardzo szybki i obsługiwać \n
dane oddzielone ewline praktycznie dowolnego rozmiaru.
Chwilę zajęło mi wymyślenie, w jaki sposób powrócić do podtytułów, takich jak:
Section Heading
Subsection Heading
Ale w końcu to rozwiązałem.
Jednak dla uproszczenia musiałem to wszystko przerobić. Podczas gdy wcześniej miałem kilka małych pętli wykonujących głównie te same rzeczy w nieco inny sposób, aby dopasować się do ich kontekstu, zmieniając sposoby rekurencji udało mi się zduplikować większość kodu. Teraz są dwie pętle - jedna drukuje, a druga sprawdza wcięcie. Oba zależą od tego samego testu - pętla drukująca rozpoczyna się po przejściu testu, a pętla wcięcia przejmuje kontrolę, gdy kończy się niepowodzeniem lub zaczyna się od pustej linii.
Cały proces jest bardzo szybki, ponieważ przez większość czasu po prostu /./d
usuwa niepustą linię i przechodzi do następnego - nawet wyniki zshall
natychmiastowego zapełniania ekranu. To się nie zmieniło.
W każdym razie jest to bardzo przydatne. Na przykład read
powyższe czynności można wykonać w następujący sposób:
mansed bash read
... i dostaje cały blok. Może przyjmować dowolne wzorce lub cokolwiek, lub wiele argumentów, chociaż pierwszy to zawsze man
strona, na której powinien szukać. Oto zdjęcie niektórych jego wyników po tym, jak to zrobiłem:
mansed bash read printf
... oba bloki są zwracane w całości. Często używam go w następujący sposób:
mansed ksh '[Cc]ommand.*'
... do czego jest całkiem użyteczny. Ponadto uzyskiwanie SYNOPS[ES]
sprawia, że jest to naprawdę przydatne:
Oto, jeśli chcesz dać mu wir - nie obwiniam cię, jeśli tego nie zrobisz.
mansed() {
MAN_KEEP_FORMATTING=1 man "$1" 2>/dev/null | ( shift
b='[:blank:]' s='[:space:]' bs=$(printf \\b) esc=$(printf '\033\[') n='\
' match=$(printf "\([${b}]*%s[${b}].*\)*" "$@")
sed -n "1p
/\n/!{ /./{ \$p;d
};x; /.*\n/!g;s///;x
:indent
/.*\n\n/{s///;x
};n;\$p;
/^\([^${s}].*\)*$/{s/./ &/;h; b indent
};x; s/.*\n[^-[]*\n.*//; /./!x;t
s/[${s}]*$//; s/\n[${b}]\{2,\}/${n} /;G;h
};
#test
/^\([${b}]*\)\([^${b}].*\n\)\1\([${b}]\)/!b indent
s//\1\2.\3/
:print
/^[${s}]*\n\./{ s///;s/\n\./${n}/
/${bs}/{s/\n/ & /g;
s/\(\(.\)${bs}\2\)\{1,\}/${esc}38;5;35m&${esc}0m/g
s/\(_${bs}[^_]\)\{1,\}/${esc}38;5;75m&${esc}0m/g
s/.${bs}//g;s/ \n /${n}/g
s/\(\(${esc}\)0m\2[^m]*m[_ ]\{,2\}\)\{2\}/_/g
};p;g;N;/\n$/!D
s//./; t print
};
#match
s/\n.*/ /; s/.${bs}//g
s/^\(${match}\).*/${n}\1/
/../{ s/^\([${s}]*\)\(.*\)/\1${n}/
x; s//${n}\1${n}. \2/; P
};D
");}
W skrócie, przepływ pracy to:
- każdy wiersz, który nie jest pusty i nie zawiera
\n
znaku ewline, jest usuwany z wyniku.
\n
znaki ewline nigdy nie występują w wejściowym obszarze wzorca. Można je uzyskać tylko w wyniku edycji.
:print
i :indent
oba są wzajemnie zależnymi zamkniętymi pętlami i są jedynym sposobem na uzyskanie \n
ewline.
:print
Cykl pętli rozpoczyna się, jeśli wiodącymi znakami w linii są ciągi \n
odstępów, po których następuje znak ewline.
:indent
Cykl rozpoczyna się na pustych liniach - lub na :print
liniach cyklicznych, które zawodzą #test
- ale :indent
usuwa wszystkie wiodące puste \n
sekwencje + ewline z jego wyniku.
- gdy
:print
zacznie, nadal będzie ciągnąć linie wejściowe, usuwać wiodące białe znaki do wartości znalezionej na pierwszym wierszu w swoim cyklu, tłumaczyć przeciążenie przecięcia i cofnięcia podskoku na kolorowe zaciski i drukować wyniki aż do #test
niepowodzenia.
- przed
:indent
rozpoczęciem najpierw sprawdza h
stare miejsce pod kątem ewentualnej kontynuacji wcięcia (takiego jak podsekcja) , a następnie kontynuuje pobieranie danych wejściowych tak długo, jak długo #test
kończy się niepowodzeniem, a dowolna linia następująca po pierwszej kontynuuje dopasowanie [-
. Gdy wiersz po pierwszym nie pasuje do tego wzorca, jest usuwany - a następnie wszystkie kolejne wiersze aż do następnej pustej linii.
#match
i #test
zmostkuj dwie zamknięte pętle.
#test
przechodzi, gdy wiodąca seria \n
odstępów jest krótsza niż seria, po której następuje ostatnia ewline w sekwencji linii.
#match
przygotowuje wiodące \n
ewline potrzebne do rozpoczęcia :print
cyklu do dowolnej :indent
sekwencji wyjściowej, która prowadzi z dopasowaniem do dowolnego argumentu wiersza poleceń. Sekwencje, które nie są renderowane jako puste - i wynikowy pusty wiersz jest przekazywany z powrotem do :indent
.