From f65a82e176cfe0f28956c438820165b6f9b910d0 Mon Sep 17 00:00:00 2001
From: jaywcjlove <398188662@qq.com>
Date: Mon, 3 Oct 2022 00:37:06 +0800
Subject: [PATCH] feat: add `bash.md` cheatsheet.
---
README.md | 1 +
docs/bash.md | 975 ++++++++++++++++++++++++++++++++++++++++
docs/quickreference.md | 7 +-
docs/xpath.md | 84 +++-
scripts/assets/bash.svg | 3 +
scripts/style.css | 6 +
6 files changed, 1053 insertions(+), 23 deletions(-)
create mode 100644 docs/bash.md
create mode 100644 scripts/assets/bash.svg
diff --git a/README.md b/README.md
index 2e4690c5..15c56aaa 100644
--- a/README.md
+++ b/README.md
@@ -7,6 +7,7 @@ Quick Reference
## 编程
+[Bash](./docs/bash.md)
[Docker](./docs/docker.md)
[Dockerfile](./docs/dockerfile.md)
[JavaScript](./docs/javascript.md)
diff --git a/docs/bash.md b/docs/bash.md
new file mode 100644
index 00000000..19b4d218
--- /dev/null
+++ b/docs/bash.md
@@ -0,0 +1,975 @@
+Bash 备忘清单
+===
+
+这是开始使用 linux bash shell 脚本的快速参考备忘单。
+
+入门
+---------------
+
+### hello.sh
+
+```bash
+#!/bin/bash
+VAR="world"
+echo "Hello $VAR!" # => Hello world!
+```
+
+执行脚本
+
+```shell
+$ bash hello.sh
+```
+
+### 变量
+
+```bash
+NAME="John"
+echo ${NAME} # => John (变量)
+echo $NAME # => John (变量)
+echo "$NAME" # => John (变量)
+echo '$NAME' # => $NAME (确切的字符串)
+echo "${NAME}!" # => John! (变量)
+NAME = "John" # => Error (关于空间)
+```
+
+### 注释
+
+```bash
+# 这是一个内联 Bash 注释。
+```
+
+```shell
+: '
+这是一个
+非常整洁的评论
+在 bash
+'
+```
+
+多行注释使用 `:'` 打开和 `'` 关闭
+
+### 参数
+
+
+表示 | 描述
+:-|-
+`$1` … `$9` | 参数 1 ... 9
+`$0` | 脚本本身的名称
+`$1` | 第一个论点
+`${10}` | 位置参数 10
+`$#` | 参数数量
+`$$` | shell 的进程 id
+`$*` | 所有论据
+`$@` | 所有参数,从第一个开始
+`$-` | 当前选项
+`$_` | 上一个命令的最后一个参数
+
+见:[特殊参数](http://wiki.bash-hackers.org/syntax/shellvars#special_parameters_and_shell_variables)
+
+
+### 函数
+
+```bash
+get_name() {
+ echo "John"
+}
+echo "You are $(get_name)"
+```
+
+见:[函数](#bash-函数)
+
+### 条件句
+
+```bash
+if [[ -z "$string" ]]; then
+ echo "String is empty"
+elif [[ -n "$string" ]]; then
+ echo "String is not empty"
+fi
+```
+
+见:[条件句](#bash-条件句)
+
+### 大括号扩展
+
+```shell
+echo {A,B}.js
+```
+
+---
+
+表示 | 描述
+:-|-
+`{A,B}` | 与 `A B` 相同
+`{A,B}.js` | 与 `A.js B.js` 相同
+`{1..5}` | 与 `1 2 3 4 5` 相同
+
+见:[大括号扩展](http://wiki.bash-hackers.org/syntax/expansion/brace)
+
+### Shell 执行
+
+```bash
+# => I'm in /当前/的/路径
+echo "I'm in $(PWD)"
+# Same as:
+echo "I'm in `pwd`"
+```
+
+见:[命令替换](http://wiki.bash-hackers.org/syntax/expansion/cmdsubst)
+
+Bash 参数扩展
+-----
+
+### 语法
+
+
+代码 | 描述
+:-|-
+`${FOO%suffix}` | 删除后缀
+`${FOO#prefix}` | 删除前缀
+`${FOO%%suffix}` | 去掉长后缀
+`${FOO##prefix}` | 删除长前缀
+`${FOO/from/to}` | 替换第一个匹配项
+`${FOO//from/to}` | 全部替换
+`${FOO/%from/to}` | 替换后缀
+`${FOO/#from/to}` | 替换前缀
+
+#### 子字符串
+
+表示 | 描述
+:-|-
+`${FOO:0:3}` | 子串 _(位置,长度)_
+`${FOO:(-3):3}` | 从右边开始的子串
+
+#### Length
+
+表示 | 描述
+:-|-
+`${#FOO}` | `$FOO` 的长度
+
+#### 默认值
+
+表示 | 描述
+:-|-
+`${FOO:-val}` | `$FOO`,如果未设置,则为 `val`
+`${FOO:=val}` | 如果未设置,则将 `$FOO` 设置为 `val`
+`${FOO:+val}` | `val` 如果设置了`$FOO`
+`${FOO:?message}` | 如果 `$FOO` 未设置,则显示消息并退出
+
+### 替代 Substitution
+
+```bash
+echo ${food:-Cake} #=> $food or "Cake"
+```
+
+```bash
+STR="/path/to/foo.cpp"
+echo ${STR%.cpp} # /path/to/foo
+echo ${STR%.cpp}.o # /path/to/foo.o
+echo ${STR%/*} # /path/to
+echo ${STR##*.} # cpp (extension)
+echo ${STR##*/} # foo.cpp (basepath)
+echo ${STR#*/} # path/to/foo.cpp
+echo ${STR##*/} # foo.cpp
+echo ${STR/foo/bar} # /path/to/bar.cpp
+```
+
+### 切片 Slicing
+
+```bash
+name="John"
+echo ${name} # => John
+echo ${name:0:2} # => Jo
+echo ${name::2} # => Jo
+echo ${name::-1} # => Joh
+echo ${name:(-1)} # => n
+echo ${name:(-2)} # => hn
+echo ${name:(-2):2} # => hn
+
+length=2
+echo ${name:0:length} # => Jo
+```
+
+见:[参数扩展](http://wiki.bash-hackers.org/syntax/pe)
+
+### 基本路径和目录路径
+
+```bash
+SRC="/path/to/foo.cpp"
+```
+
+```bash
+BASEPATH=${SRC##*/}
+echo $BASEPATH # => "foo.cpp"
+
+DIRPATH=${SRC%$BASEPATH}
+echo $DIRPATH # => "/path/to/"
+```
+
+### Transform
+
+```bash
+STR="HELLO WORLD!"
+echo ${STR,} # => hELLO WORLD!
+echo ${STR,,} # => hello world!
+
+STR="hello world!"
+echo ${STR^} # => Hello world!
+echo ${STR^^} # => HELLO WORLD!
+
+ARR=(hello World)
+echo "${ARR[@],}" # => hello world
+echo "${ARR[@]^}" # => Hello World
+```
+
+Bash 数组
+------
+
+### 定义数组
+
+```bash
+Fruits=('Apple' 'Banana' 'Orange')
+
+Fruits[0]="Apple"
+Fruits[1]="Banana"
+Fruits[2]="Orange"
+
+ARRAY1=(foo{1..2}) # => foo1 foo2
+ARRAY2=({A..D}) # => A B C D
+
+# 合并 => foo1 foo2 A B C D
+ARRAY3=(${ARRAY1[@]} ${ARRAY2[@]})
+
+# 声明构造
+declare -a Numbers=(1 2 3)
+Numbers+=(4 5) # 附加 => 1 2 3 4 5
+```
+
+### 索引
+
+:- | -
+:- | -
+`${Fruits[0]}` | 第一个元素
+`${Fruits[-1]}` | 最后一个元素
+`${Fruits[*]}` | 所有元素
+`${Fruits[@]}` | 所有元素
+`${#Fruits[@]}` | 总数
+`${#Fruits}` | 第一节长度
+`${#Fruits[3]}` | 第n个长度
+`${Fruits[@]:3:2}` | 范围
+`${!Fruits[@]}` | 所有 Key
+
+### 迭代 Iteration
+
+```bash
+Fruits=('Apple' 'Banana' 'Orange')
+for e in "${Fruits[@]}"; do
+ echo $e
+done
+```
+#### With index
+```bash
+for i in "${!Fruits[@]}"; do
+ printf "%s\t%s\n" "$i" "${Fruits[$i]}"
+done
+```
+
+### 操作
+
+
+```bash
+Fruits=("${Fruits[@]}" "Watermelon") # 推
+Fruits+=('Watermelon') # 也推
+Fruits=( ${Fruits[@]/Ap*/} ) # 通过正则表达式匹配删除
+unset Fruits[2] # 删除一项
+Fruits=("${Fruits[@]}") # 复制
+Fruits=("${Fruits[@]}" "${Veggies[@]}") # 连接
+lines=(`cat "logfile"`) # 从文件中读取
+```
+
+### 数组作为参数
+
+```bash
+function extract()
+{
+ local -n myarray=$1
+ local idx=$2
+ echo "${myarray[$idx]}"
+}
+Fruits=('Apple' 'Banana' 'Orange')
+extract Fruits 2 # => Orangle
+```
+
+Bash 字典
+------------
+
+### 定义
+
+```bash
+declare -A sounds
+```
+
+```bash
+sounds[dog]="bark"
+sounds[cow]="moo"
+sounds[bird]="tweet"
+sounds[wolf]="howl"
+```
+
+### 使用字典
+
+```bash
+echo ${sounds[dog]} # Dog's sound
+echo ${sounds[@]} # All values
+echo ${!sounds[@]} # All keys
+echo ${#sounds[@]} # Number of elements
+unset sounds[dog] # Delete dog
+```
+
+### 迭代
+
+```bash
+for val in "${sounds[@]}"; do
+ echo $val
+done
+```
+
+---
+
+```bash
+for key in "${!sounds[@]}"; do
+ echo $key
+done
+```
+
+Bash 条件句
+------------
+
+### 整数条件
+
+条件 | 描述
+:- | -
+`[[ NUM -eq NUM ]]` | 等于 Equal |
+`[[ NUM -ne NUM ]]` | 不等于 Not equal |
+`[[ NUM -lt NUM ]]` | 少于 Less than |
+`[[ NUM -le NUM ]]` | 小于或等于 Less than or equal |
+`[[ NUM -gt NUM ]]` | 大于 Greater than |
+`[[ NUM -ge NUM ]]` | 大于或等于 Greater than or equal |
+`(( NUM < NUM ))` | 少于
+`(( NUM <= NUM ))` | 小于或等于
+`(( NUM > NUM ))` | 比...更棒
+`(( NUM >= NUM ))` | 大于或等于
+
+### 字符串条件
+
+条件 | 描述
+:- | -
+`[[ -z STR ]]` | 空字符串
+`[[ -n STR ]]` | 非空字符串
+`[[ STR == STR ]]` | 平等的
+`[[ STR = STR ]]` | 相等(同上)
+`[[ STR < STR ]]` | 小于 _(ASCII)_
+`[[ STR > STR ]]` | 大于 _(ASCII)_
+`[[ STR != STR ]]` | 不相等
+`[[ STR =~ STR ]]` | 正则表达式
+
+### 例子
+
+
+#### 字符串
+
+```bash
+if [[ -z "$string" ]]; then
+ echo "String is empty"
+elif [[ -n "$string" ]]; then
+ echo "String is not empty"
+else
+ echo "This never happens"
+fi
+```
+
+#### 组合
+
+```bash
+if [[ X && Y ]]; then
+ ...
+fi
+```
+
+#### 相等
+
+```bash
+if [[ "$A" == "$B" ]]; then
+ ...
+fi
+```
+
+#### 正则表达式
+
+```bash
+if [[ '1. abc' =~ ([a-z]+) ]]; then
+ echo ${BASH_REMATCH[1]}
+fi
+```
+
+#### 更小
+
+```bash
+if (( $a < $b )); then
+ echo "$a is smaller than $b"
+fi
+```
+
+#### 存在
+
+```bash
+if [[ -e "file.txt" ]]; then
+ echo "file exists"
+fi
+```
+
+### 文件条件
+
+
+条件 | 描述
+:- | -
+`[[ -e FILE ]]` | 存在
+`[[ -d FILE ]]` | 目录
+`[[ -f FILE ]]` | 文件
+`[[ -h FILE ]]` | 符号链接
+`[[ -s FILE ]]` | 大小 > 0 字节
+`[[ -r FILE ]]` | 可读
+`[[ -w FILE ]]` | 可写
+`[[ -x FILE ]]` | 可执行文件
+`[[ f1 -nt f2 ]]` | f1 比 f2 新
+`[[ f1 -ot f2 ]]` | f2 早于 f1
+`[[ f1 -ef f2 ]]` | 相同的文件
+
+
+### 更多条件
+
+条件 | 描述
+:- | -
+`[[ -o noclobber ]]` | 如果启用 OPTION
+`[[ ! EXPR ]]` | 不是 Not
+`[[ X && Y ]]` | 和 And
+`[[ X \|\| Y ]]` | 或者 Or
+
+### 逻辑和,或
+
+```bash
+if [ "$1" = 'y' -a $2 -gt 0 ]; then
+ echo "yes"
+fi
+if [ "$1" = 'n' -o $2 -lt 0 ]; then
+ echo "no"
+fi
+```
+
+Bash 循环
+-----
+
+### 基本 for 循环
+
+```bash
+for i in /etc/rc.*; do
+ echo $i
+done
+```
+
+### 类似 C 的 for 循环
+
+```bash
+for ((i = 0 ; i < 100 ; i++)); do
+ echo $i
+done
+```
+
+### 范围
+
+
+```bash
+for i in {1..5}; do
+ echo "Welcome $i"
+done
+```
+
+#### 具有步长
+
+```bash
+for i in {5..50..5}; do
+ echo "Welcome $i"
+done
+```
+
+### 自动递增
+
+```bash
+i=1
+while [[ $i -lt 4 ]]; do
+ echo "Number: $i"
+ ((i++))
+done
+```
+
+### 自动递增
+
+```bash
+i=3
+while [[ $i -gt 0 ]]; do
+ echo "Number: $i"
+ ((i--))
+done
+```
+
+### Continue
+
+```bash {data=3,5}
+for number in $(seq 1 3); do
+ if [[ $number == 2 ]]; then
+ continue;
+ fi
+ echo "$number"
+done
+```
+
+### Break
+
+```bash
+for number in $(seq 1 3); do
+ if [[ $number == 2 ]]; then
+ # Skip entire rest of loop.
+ break;
+ fi
+ # This will only print 1
+ echo "$number"
+done
+```
+
+### Until
+
+```bash
+count=0
+until [ $count -gt 10 ]; do
+ echo "$count"
+ ((count++))
+done
+```
+
+### 永远
+
+```bash
+while true; do
+ # here is some code.
+done
+```
+
+### 永远(简写)
+
+```bash
+while :; do
+ # here is some code.
+done
+```
+
+
+### 正在读取行
+
+```bash
+cat file.txt | while read line; do
+ echo $line
+done
+```
+
+Bash 函数
+---------
+
+### 定义函数
+
+```bash
+myfunc() {
+ echo "hello $1"
+}
+```
+
+```bash
+# 同上(替代语法)
+function myfunc() {
+ echo "hello $1"
+}
+```
+
+```bash
+myfunc "John"
+```
+
+### 返回值
+
+```bash
+myfunc() {
+ local myresult='some value'
+ echo $myresult
+}
+```
+
+```bash
+result="$(myfunc)"
+```
+
+### 正在引发错误
+
+```bash
+myfunc() {
+ return 1
+}
+```
+
+```bash
+if myfunc; then
+ echo "success"
+else
+ echo "failure"
+fi
+```
+
+Bash 选项
+-------
+
+
+### 选项
+
+```bash
+# 避免覆盖文件
+# (echo "hi" > foo)
+set -o noclobber
+
+# 用于出错时退出
+# 避免级联错误
+set -o errexit
+
+# 揭示隐藏的失败
+set -o pipefail
+
+# 公开未设置的变量
+set -o nounset
+```
+
+### 全局选项
+
+```bash
+# 不匹配的 glob 被删除
+# ('*.foo' => '')
+shopt -s nullglob
+
+# 不匹配的 glob 抛出错误
+shopt -s failglob
+
+# 不区分大小写的球体
+shopt -s nocaseglob
+
+# 通配符匹配点文件
+# ("*.sh" => ".foo.sh")
+shopt -s dotglob
+
+# 允许 ** 进行递归匹配
+# ('lib/**/*.rb' => 'lib/a/b/c.rb')
+shopt -s globstar
+```
+
+Bash 历史
+-------
+
+
+### 命令
+
+命令 | 描述
+:- | -
+`history` | 显示历史
+`sudo !!` | 使用 sudo 运行上一个命令
+`shopt -s histverify` | 不要立即执行扩展结果
+
+### 表达式
+
+表达式 | 描述
+:- | -
+`!$` | 展开最新命令的最后一个参数
+`!*` | 展开最新命令的所有参数
+`!-n` | 展开第 `n` 个最近的命令
+`!n` | 展开历史中的第 `n` 个命令
+`!` | 展开最近调用的命令 ``
+
+### 操作
+
+代码 | 描述
+:- | -
+`!!` | 再次执行最后一条命令
+`!!:s///` | 在最近的命令中将第一次出现的 `` 替换为 ``
+`!!:gs///` | 在最近的命令中将所有出现的 `` 替换为 ``
+`!$:t` | 仅从最近命令的最后一个参数扩展基本名称
+`!$:h` | 仅从最近命令的最后一个参数展开目录
+
+`!!` 和 `!$` 可以替换为任何有效的扩展。
+
+### 切片 Slices
+
+代码 | 描述
+:- | -
+`!!:n` | 仅扩展最近命令中的第 `n` 个标记(命令为 `0`;第一个参数为 `1`)
+`!^` | 从最近的命令展开第一个参数
+`!$` | 从最近的命令中展开最后一个标记
+`!!:n-m` | 从最近的命令扩展令牌范围
+`!!:n-$` | 从最近的命令中将第 `n` 个标记展开到最后
+
+`!!` 可以替换为任何有效的扩展,即 `!cat`、`!-2`、`!42` 等。
+
+
+各种各样的
+-------------
+
+### 数值计算
+
+```bash
+$((a + 200)) # Add 200 to $a
+```
+
+```bash
+$(($RANDOM%200)) # Random number 0..199
+```
+
+### 子 shell
+
+```bash
+(cd somedir; echo "I'm now in $PWD")
+pwd # still in first directory
+```
+
+
+### 检查命令
+
+```bash
+command -V cd
+#=> "cd is a function/alias/whatever"
+```
+
+### 重定向
+
+
+```bash
+python hello.py > output.txt # 标准输出到(文件)
+python hello.py >> output.txt # 标准输出到(文件),追加
+python hello.py 2> error.log # 标准错误到(文件)
+python hello.py 2>&1 # 标准错误到标准输出
+python hello.py 2>/dev/null # 标准错误到(空null)
+python hello.py &>/dev/null # 标准输出和标准错误到(空null)
+```
+
+```bash
+python hello.py < foo.txt # 将 foo.txt 提供给 python 的标准输入
+```
+
+
+### 来源相对
+
+```bash
+source "${0%/*}/../share/foo.sh"
+```
+
+### 脚本目录
+
+```bash
+DIR="${0%/*}"
+```
+
+### Case/switch
+
+```bash
+case "$1" in
+ start | up)
+ vagrant up
+ ;;
+ *)
+ echo "Usage: $0 {start|stop|ssh}"
+ ;;
+esac
+```
+
+
+### 陷阱错误
+
+
+```bash
+trap 'echo Error at about $LINENO' ERR
+```
+
+或者
+
+```bash
+traperr() {
+ echo "ERROR: ${BASH_SOURCE[1]} at about ${BASH_LINENO[0]}"
+}
+set -o errtrace
+trap traperr ERR
+```
+
+### printf
+
+```bash
+printf "Hello %s, I'm %s" Sven Olga
+#=> "Hello Sven, I'm Olga
+
+printf "1 + 1 = %d" 2
+#=> "1 + 1 = 2"
+
+printf "Print a float: %f" 2
+#=> "Print a float: 2.000000"
+```
+
+### 获取选项
+
+
+```bash
+while [[ "$1" =~ ^- && ! "$1" == "--" ]]; do case $1 in
+ -V | --version )
+ echo $version
+ exit
+ ;;
+ -s | --string )
+ shift; string=$1
+ ;;
+ -f | --flag )
+ flag=1
+ ;;
+esac; shift; done
+if [[ "$1" == '--' ]]; then shift; fi
+```
+
+### 检查命令的结果
+
+
+```bash
+if ping -c 1 google.com; then
+ echo "看来您的互联网连接正常"
+fi
+```
+
+### 特殊变量
+
+
+表达式 | 描述
+:- | -
+`$?` | 最后一个任务的退出状态
+`$!` | 最后一个后台任务的 PID
+`$$` | shell PID
+`$0` | shell 脚本的文件名
+
+见[特殊参数](http://wiki.bash-hackers.org/syntax/shellvars#special_parameters_and_shell_variables)。
+
+
+### grep 检查
+
+
+```bash
+if grep -q 'foo' ~/.bash_history; then
+ echo "您过去似乎输入过“foo”"
+fi
+```
+
+
+### 反斜杠转义
+
+
+-
+- \!
+- \"
+- \#
+- \&
+- \'
+- \(
+- \)
+- \,
+- \;
+- \<
+- \>
+- \[
+- \|
+- \\
+- \]
+- \^
+- \{
+- \}
+- \`
+- \$
+- \*
+- \?
+
+
+使用 `\` 转义这些特殊字符
+
+### Heredoc
+
+```sh
+cat <` 列表样式
### 颜色标签
:- | -
:- | -
-`` | 黄色
-`` | 紫色
-`` 或 \`\`
| 绿色
+`` | 黄色
+`` | 紫色
+`` 或 \`\`
| 绿
`色`
diff --git a/docs/xpath.md b/docs/xpath.md
index fb9b156a..015ed745 100644
--- a/docs/xpath.md
+++ b/docs/xpath.md
@@ -7,12 +7,18 @@ XPath 选择器
--------
### 入门
+
XPath 即为 XML 路径语言(XML Path Language),它是一种用来确定XML文档中某部分位置的计算机语言。
- [Xpath test bed](http://www.whitebeam.org/library/guide/TechNotes/xpathtestbed.rhtm) _(whitebeam.org)_
+- XPath 代表 XML 路径语言
+- XPath 使用 `类似路径` 语法识别和导航 XML 文档中的节点
+- XPath 包含超过 200 个内置函数
+- XPath 是 XSLT 标准中的主要元素
+- XPath 是 W3C 推荐的
-在 Firefox 或 Chrome 控制台中测试:
+在 `Firefox` 或 `Chrome` 控制台中测试:
```js
$x('/html/body')
@@ -71,17 +77,20 @@ $x('//a[text()="XPath"]')[0].click()
| `//h1/following-sibling::[@id="id"]` | h1 ~ #id |
-### jQuery
+### 最有用的路径表达式
| Xpath | CSS |
|----------------------------------|----------------------------|
-| `//ul/li/..` | $('ul > li').parent() |
-| `//li/ancestor-or-self::section` | $('li').closest('section') |
-| `//a/@href` | $('a').attr('href') |
-| `//span/text()` | $('span').text() |
+`nodename` | 选择名称为 `nodename` 的所有节点
+`/` | 从根节点中选择
+`//` | 从当前节点中选择文档中与选择匹配的节点,无论它们在哪里
+`.` | 选择当前节点
+`..` | 选择当前节点的父节点
+`@` | 选择属性
### 杂项选择器
+
| Xpath | CSS |
|-----------------------------------|---------------------------|
@@ -92,9 +101,44 @@ $x('//a[text()="XPath"]')[0].click()
| `//ul[*]` | 有孩子 |
| `//ul[li]` | 有孩子(具体) |
| `//a[@name or @href]` | 或逻辑 |
-| `//a | //div` | 联合(加入结果) |
+| `//a \| //div` | 联合(加入结果) |
+### jQuery
+
+
+| Xpath | CSS |
+|----------------------------------|----------------------------|
+| `//ul/li/..` | $('ul > li').parent() |
+| `//li/ancestor-or-self::section` | $('li').closest('section') |
+| `//a/@href` | $('a').attr('href') |
+| `//span/text()` | $('span').text() |
+
+
+### 运算符
+
+
+
+运算符 | 说明 | 示例
+:- | - | -
+`\|` | 计算两个节点集 | `//book \| //cd`
+`+` | 添加 | `6 + 4`
+`-` | 减法 | `6 - 4`
+`*` | 乘法 | `6 * 4`
+`div` | 分配 | `8 div 4`
+`=` | 平等的 | `price=9.80`
+`!=` | 不相等 | `price!=9.80`
+`<` | 小于 | `price<9.80`
+`<=` | 小于或等于 | `price<=9.80`
+`>` | 大于 | `price>9.80`
+`>=` | 大于或等于 | `price>=9.80`
+`or` | 或者 | `price=9.80` or `price=9.70`
+`and` | 和 | `price>9.00` and `price<9.90`
+`mod` | 模数(除法余数) | `5` mod `2`
+
+
+
+
XPath 表达式
-----------
@@ -311,19 +355,19 @@ XPath Axes
| Axis | Abbrev | Notes |
|--------------------|--------|-------|
-| `ancestor` | | |
-| `ancestor-or-self` | | |
-| `attribute` | `@` | `@href` 是 `attribute::href` 的缩写 |
-| `child` | | `div` 是 `child::div` 的缩写 |
-| `descendant` | | |
-| `descendant-or-self` | `//` | `//` 是 `/descendant-or-self::node()/`的缩写 |
-| `namespace` | | |
-| `self` | `.` | `.` 是 `self::node()` 的缩写 |
-| `parent` | `..` | `..` 是 `parent::node()` 的缩写 |
-| `following` | | |
-| `following-sibling` | | |
-| `preceding` | | |
-| `preceding-sibling` | | |
+`ancestor` | | 选择当前节点的所有祖先(父母、祖父母等)
+`ancestor-or-self` | | 选择当前节点所有祖先(父、祖父等)和当前节点本身
+`attribute` | `@` | `@href` 是 `attribute::href` 的缩写
+`child` | | `div` 是 `child::div` 的缩写
+`descendant` | | 选择当前节点的所有后代(子、孙等)
+`descendant-or-self` | `//` | `//` 是 `/descendant-or-self::node()/`的缩写 选择当前节点和当前节点本身的所有后代(子、孙等)
+`namespace` | | 选择当前节点的所有命名空间节点
+`self` | `.` | `.` 是 `self::node()` 的缩写,选择当前节点
+`parent` | `..` | `..` 是 `parent::node()` 的缩写,选择当前节点的父节点
+`following` | | 选择文档中当前节点结束标记之后的所有内容
+`following-sibling` | | 选择当前节点之后的所有兄弟节点
+`preceding` | | 选择文档中出现在当前节点之前的所有节点,除了祖先、属性节点和命名空间节点
+`preceding-sibling` | | 选择当前节点之前的所有兄弟节点
您还可以使用其他轴。
diff --git a/scripts/assets/bash.svg b/scripts/assets/bash.svg
new file mode 100644
index 00000000..40db03bf
--- /dev/null
+++ b/scripts/assets/bash.svg
@@ -0,0 +1,3 @@
+
diff --git a/scripts/style.css b/scripts/style.css
index d5c60ca9..93f610dd 100644
--- a/scripts/style.css
+++ b/scripts/style.css
@@ -543,6 +543,12 @@ body:not(.home) .h2wrap > h2 a::after {
grid-template-columns: repeat(1,minmax(0,1fr));
}
+.h3wrap > .wrap-body ul:not(:last-child),
+.h3wrap > .wrap-body ol,
+.h3wrap > .wrap-body dl {
+ margin-bottom: 0;
+}
+
.h2wrap-body ul li,
.h2wrap-body ol li,
.h2wrap-body dl li {