Meskipun memang benar bahwa beberapa builtin shell mungkin memiliki sedikit menunjukkan dalam manual lengkap - terutama untuk bash
builtin spesifik yang Anda hanya akan menggunakan pada sistem GNU (orang-orang GNU, sebagai aturan, sebagai aturan, tidak percaya pada man
dan lebih suka info
halaman mereka sendiri ) - sebagian besar utilitas POSIX - shell builtin atau lainnya - sangat terwakili dalam Panduan Programmer POSIX.
Berikut adalah kutipan dari bagian bawah saya man sh
(yang mungkin sekitar 20 halaman atau lebih ...)
Semua orang yang ada, dan lain-lain tidak disebutkan seperti set
, read
, break
... baik, saya tidak perlu nama mereka semua. Tetapi perhatikan (1P)
bagian kanan bawah - ini menunjukkan seri manual kategori 1 POSIX - itu adalah man
halaman yang saya bicarakan.
Mungkin Anda hanya perlu menginstal paket? Ini terlihat menjanjikan untuk sistem Debian. Meskipun help
berguna, jika Anda dapat menemukannya, Anda pasti harus mendapatkan POSIX Programmer's Guide
seri itu. Ini bisa sangat membantu. Dan halaman konstituennya sangat detail.
Selain itu, shell builtin hampir selalu terdaftar di bagian spesifik dari manual shell tertentu. zsh
, misalnya, memiliki seluruh man
halaman terpisah untuk itu - (Saya pikir totalnya 8 atau 9 zsh
halaman individu - termasuk zshall
yang sangat besar.)
Anda grep
man
tentu saja dapat:
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
... yang cukup dekat dengan apa yang saya lakukan ketika mencari man
halaman shell . Tetapi help
cukup bagus bash
dalam banyak kasus.
Saya sebenarnya telah mengerjakan sed
skrip untuk menangani hal-hal semacam ini baru-baru ini. Begitulah cara saya meraih bagian pada gambar di atas. Ini masih lebih lama dari yang saya suka, tetapi membaik - dan bisa sangat berguna. Dalam iterasi saat ini ia akan cukup andal mengekstrak bagian teks konteks-sensitif sebagai dicocokkan dengan bagian atau judul ayat berdasarkan pada pola [a] yang diberikan pada baris perintah. Ini warna output dan mencetak ke stdout.
Ini bekerja dengan mengevaluasi level indentasi. Jalur input non-kosong umumnya diabaikan, tetapi ketika bertemu dengan garis kosong, ia mulai memperhatikan. Ia mengumpulkan garis-garis dari sana sampai ia memverifikasi bahwa urutan saat ini jelas membuat indentasi lebih dalam daripada yang dilakukan baris pertama sebelum baris kosong lainnya terjadi atau ia menjatuhkan thread dan menunggu untuk kosong berikutnya. Jika tes ini berhasil, ia mencoba untuk mencocokkan garis memimpin dengan args baris perintahnya.
Ini berarti bahwa pertandingan pola akan cocok:
heading
match ...
...
...
text...
..dan..
match
text
..tapi tidak..
heading
match
match
notmatch
..atau..
text
match
match
text
more text
Jika kecocokan bisa didapat maka mulai mencetak. Ini akan menghapus kosong baris terkemuka yang cocok dari semua baris yang dicetaknya - jadi tidak peduli level indent yang ditemukannya, garis itu mencetaknya seolah-olah berada di atas. Ia akan terus mencetak hingga menemukan baris lain pada level indentasi yang sama atau kurang dari garis yang cocok - sehingga seluruh bagian diambil hanya dengan korek api heading, termasuk semua / semua sub-bagian, paragraf yang mungkin dikandungnya.
Jadi pada dasarnya jika Anda memintanya untuk mencocokkan suatu pola, ia hanya akan melakukannya terhadap judul subjek dan akan mewarnai dan mencetak semua teks yang ditemukannya di dalam bagian yang dikepalai oleh kecocokannya. Tidak ada yang disimpan karena ia melakukan ini kecuali indentasi baris pertama Anda - dan karenanya bisa sangat cepat dan menangani \n
input yang dipisahkan secara ewline untuk hampir semua ukuran.
Butuh beberapa saat bagi saya untuk mengetahui cara berulang ke subpos seperti berikut:
Section Heading
Subsection Heading
Tapi saya akhirnya mengatasinya.
Saya memang harus mengerjakan ulang semuanya demi kesederhanaan. Sementara sebelum saya memiliki beberapa loop kecil melakukan sebagian besar hal yang sama dengan cara yang sedikit berbeda agar sesuai dengan konteks mereka, dengan memvariasikan cara rekursi mereka, saya berhasil menduplikasi sebagian besar kode. Sekarang ada dua loop - satu cetakan dan satu cek indentasi. Keduanya tergantung pada tes yang sama - loop cetak dimulai ketika tes lulus dan loop indentasi mengambil alih ketika gagal atau dimulai pada baris kosong.
Seluruh proses ini sangat cepat karena sebagian besar waktu hanya /./d
menghapus garis yang tidak kosong dan beralih ke yang berikutnya - bahkan hasil dari zshall
mengisi layar secara instan. Ini belum berubah.
Bagaimanapun, ini sangat berguna sejauh ini. Sebagai contoh, read
hal di atas dapat dilakukan seperti:
mansed bash read
... Dan itu mendapat seluruh blok. Itu bisa mengambil pola atau apa saja, atau beberapa argumen, meskipun yang pertama selalu man
halaman di mana ia harus mencari. Berikut adalah gambar dari beberapa output setelah saya melakukannya:
mansed bash read printf
... kedua blok dikembalikan utuh. Saya sering menggunakannya seperti:
mansed ksh '[Cc]ommand.*'
... yang ini cukup berguna. Juga, SYNOPS[ES]
membuatnya sangat berguna:
Ini dia jika Anda ingin berputar - saya tidak akan menyalahkan Anda jika Anda tidak melakukannya.
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
");}
Secara singkat, alur kerjanya adalah:
- baris apa pun yang tidak kosong dan yang tidak mengandung
\n
karakter ewline dihapus dari output.
\n
karakter garis tidak pernah terjadi dalam ruang pola input. Mereka hanya dapat dimiliki sebagai hasil edit.
:print
dan :indent
keduanya merupakan loop tertutup yang saling bergantung dan merupakan satu-satunya cara untuk mendapatkan \n
ewline.
:print
Siklus lingkaran dimulai jika karakter utama pada suatu baris adalah serangkaian kosong diikuti oleh \n
karakter ewline.
:indent
Siklus dimulai pada baris kosong - atau pada :print
baris siklus yang gagal #test
- tetapi :indent
menghapus semua \n
urutan baris + kosong awal dari outputnya.
- begitu
:print
dimulai, ia akan terus menarik garis input, mengosongkan spasi putih hingga jumlah yang ditemukan pada baris pertama dalam siklusnya, menerjemahkan overstrike dan understrike backspace lolos ke terminal warna lolos, dan mencetak hasilnya hingga #test
gagal.
- sebelum
:indent
mulai, pertama-tama periksa h
ruang lama untuk kemungkinan kelanjutan inden yang mungkin (seperti Subbagian) , dan kemudian terus menarik input selama #test
gagal dan setiap baris setelah yang pertama terus cocok [-
. Ketika sebuah baris setelah yang pertama tidak cocok dengan pola itu dihapus - dan kemudian semua baris berikut sampai baris kosong berikutnya.
#match
dan #test
menjembatani dua loop tertutup.
#test
lewat ketika deretan kosong depan lebih pendek dari seri diikuti oleh baris terakhir \n
dalam urutan garis.
#match
menambahkan beberapa baris utama yang \n
diperlukan untuk memulai :print
siklus ke :indent
urutan output mana pun yang mengarah pada kecocokan dengan setiap baris perintah. Urutan yang tidak dirender kosong - dan garis kosong yang dihasilkan dilewatkan kembali ke :indent
.