##* %%* linux变量处理

本文详细解读Shell中变量替换语法,包括#、%符号的使用方法,以及如何利用${}

假设我们定义了一个变量为:
file=/dir1/dir2/dir3/my.file.txt

可以用${ }分别替换得到不同的值:
${file#*/}:删掉第一个/ 及其左边的字符串:dir1/dir2/dir3/my.file.txt
${file##*/}:删掉最后一个/ 及其左边的字符串:my.file.txt
${file#*.}:删掉第一个. 及其左边的字符串:file.txt
${file##*.}:删掉最后一个. 及其左边的字符串:txt
${file%/*}
:删掉最后一个 / 及其右边的字符串:/dir1/dir2/dir3
${file%%/*}:删掉第一个/ 及其右边的字符串:(空值)
${file%.*}:删掉最后一个 . 及其右边的字符串:/dir1/dir2/dir3/my.file
${file%%.*}:删掉第一个 . 及其右边的字符串:/dir1/dir2/dir3/my

记忆的方法为:
# 是 去掉左边(键盘上#在 $ 的左边)
%是去掉右边(键盘上% 在$ 的右边)
单一符号是最小匹配;两个符号是最大匹配
${file:0:5}:提取最左边的5 个字节:/dir1
${file:5:5}
:提取第5 个字节右边的连续5个字节:/dir2

也可以对变量值里的字符串作替换:
${file/dir/path}
:将第一个dir 替换为path/path1/dir2/dir3/my.file.txt
${file//dir/path}
:将全部dir 替换为path/path1/path2/path3/my.file.txt

利用${ } 还可针对不同的变数状态赋值(沒设定、空值、非空值)
${file-my.file.txt}
:假如$file 沒有设定,則使用my.file.txt 作传回值。(空值及非空值時不作处理)
${file:-my.file.txt}
:假如$file 沒有設定或為空值,則使用my.file.txt 作傳回值。(非空值時不作处理)
${file+my.file.txt}
:假如$file 設為空值或非空值,均使用my.file.txt 作傳回值。(沒設定時不作处理)
${file:+my.file.txt}
:若$file 為非空值,則使用my.file.txt 作傳回值。(沒設定及空值時不作处理)
${file=my.file.txt}
:若$file 沒設定,則使用my.file.txt 作傳回值,同時將$file 賦值為my.file.txt (空值及非空值時不作处理)
${file:=my.file.txt}
:若$file 沒設定或為空值,則使用my.file.txt 作傳回值,同時將$file 賦值為my.file.txt (非空值時不作处理)
${file?my.file.txt}
:若$file 沒設定,則將my.file.txt 輸出至STDERR(空值及非空值時不作处理)

${file:?my.file.txt} :若$file 没设定或为空值,则将my.file.txt 输出至STDERR(非空值時不作处理)

${#var} 可计算出变量值的长度:

${#file} 可得到27 ,因为/dir1/dir2/dir3/my.file.txt 27个字节

<think>我们正在分析一个sscanf函数调用:`sscanf(buffer, "%*s %*d %*d %*d %*d %*d %*d %*d %*d %*d %d %d %d", pInSegs, pOutSegs, pRetransSegs);` 1. 首先,sscanf函数用于从字符串中读取格式化输入。这里是从`buffer`字符串中读取。 2. 格式化字符串:`"%*s %*d %*d %*d %*d %*d %*d %*d %*d %*d %d %d %d"` - `%*s`:表示读取一个字符串,但`*`表示忽略(不赋值给任何变量),所以这里跳过第一个字符串。 - 接下来有9个`%*d`:表示读取9个整数,但同样忽略它们(因为有`*`修饰符)。 - 然后有3个`%d`:表示读取三个整数,并且没有`*`,所以这三个整数将会被赋值给后面的变量。 3. 后面的参数:`pInSegs, pOutSegs, pRetransSegs`。这三个参数应该是整型指针(或者说是整型变量的地址),用于存储读取到的三个整数值。 因此,这条语句的作用是:从`buffer`字符串中跳过第一个字符串和接下来的9个整数,然后读取接下来的三个整数,分别存储到`pInSegs`、`pOutSegs`和`pRetransSegs`所指向的变量中。 举个例子,假设`buffer`字符串的内容是: "Tcp: 100 200 300 400 500 600 700 800 900 1000 1100 1200 1300" 那么: - `%*s`会跳过"Tcp:" - 接下来的9个`%*d`会跳过100,200,...,900(共9个整数) - 然后读取1000存入pInSegs指向的变量 - 读取1100存入pOutSegs指向的变量 - 读取1200存入pRetransSegs指向的变量 注意:实际应用中,`buffer`可能是类似于`/proc/net/snmp`文件中读取的一行,该文件包含TCP/IP协议的统计信息。通常,`/proc/net/snmp`中有一行是TCP统计信息,其格式为: "Tcp: RtoAlgorithm RtoMin RtoMax MaxConn ActiveOpens PassiveOpens AttemptFails EstabResets CurrEstab InSegs OutSegs RetransSegs ..." 因此,上面的代码可能是为了提取`InSegs`(接收的段数)、`OutSegs`(发送的段数)和`RetransSegs`(重传的段数)这三个统计值。 具体到该格式化字符串: - 第一个字段是字符串"Tcp:",被跳过。 - 接下来9个字段(整数)被跳过(对应于RtoAlgorithm, RtoMin, RtoMax, MaxConn, ActiveOpens, PassiveOpens, AttemptFails, EstabResets, CurrEstab)。 - 然后读取第10、11、12个整数,即InSegs, OutSegs, RetransSegs。 所以,这段代码的作用是从TCP统计行中提取这三个关键指标。 注意:在Linux的`/proc/net/snmp`中,第二行才是当前值(第一行是标题),所以通常需要读取两行,然后第二行才是数据行。这里我们假设buffer是第二行(即数据行)。 总结: 该代码从包含TCP统计信息的字符串中,跳过开头的字符串和9个整数,然后读取接下来的三个整数,分别作为入站段数、出站段数和重传段数。 引用说明:我们在解释中使用了用户提供的参考信息,特别是关于sscanf的基本用法,以及%*的忽略功能。但用户提供的参考信息中提到了%n,这里并没有用到%n,所以主要参考的是sscanf的忽略功能(*修饰符)和读取整数(%d)的功能。 现在,根据要求,我们需要生成相关问题。 </think>### `sscanf` 代码解析:含义与作用 #### 1. 代码含义 ```c sscanf(buffer, "%*s %*d %*d %*d %*d %*d %*d %*d %*d %*d %d %d %d", pInSegs, pOutSegs, pRetransSegs); ``` 这是C语言的字符串格式化输入函数,作用是从`buffer`字符串中**选择性提取特定数值**: - `%*s` :跳过1个字符串(`*`表示忽略不保存) - `%*d` :跳过9个整数值(共9个`%*d`) - `%d` :提取最后3个整数值(无`*`表示保存) #### 2. 参数对应关系 | 格式化占位符 | 作用 | 目标变量 | |--------------------|---------------|--------------| | `%*s` | 跳过1个字符串 | - | | `%*d` $\times 9$ | 跳过9个整数 | - | | 第一个 `%d` | 提取整数 | `*pInSegs` | | 第二个 `%d` | 提取整数 | `*pOutSegs` | | 第三个 `%d` | 提取整数 | `*pRetransSegs` | #### 3. 典型应用场景 这段代码常见于**网络统计数据处理**,例如解析Linux系统文件`/proc/net/snmp`中的TCP行: ``` Tcp: 1 2 3 4 5 6 7 8 9 10 183642 174529 1203 ``` - 跳过开头的`"Tcp:"`和9个统计值 - 提取最后三个关键指标: - `InSegs`:接收的TCP段数量 - `OutSegs`:发送的TCP段数量 - `RetransSegs`:重传的TCP段数量 #### 4. 数学表达式解释 设输入字符串为: $$ \text{buffer} = S_0\ D_1\ D_2\ \cdots\ D_9\ D_{10}\ D_{11}\ D_{12} $$ 其中: - $S_0$ 是被跳过的字符串 - $D_1$ 到 $D_9$ 是被跳过的9个整数 - $D_{10}, D_{11}, D_{12}$ 是提取的3个整数 提取过程可表示为: $$ \begin{align*} *pInSegs &= D_{10} \\ *pOutSegs &= D_{11} \\ *pRetransSegs &= D_{12} \end{align*} $$ #### 5. 关键知识点 1. **`%*`修饰符**:抑制赋值,跳过匹配项 2. **指针参数**:`pInSegs`等需指向已分配内存的整型变量 3. **返回值**:函数返回成功赋值的变量数(此处应为3) > 此技术常用于高效跳过无关数据,直接定位关键指标[^1]。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值