概述
本文讲述的是使用shell脚本对文本进行处理,提取出所需要的字符串内容
背景
在linux 的环境下,经常会出现对一些文本内容进行提取,比如查找并提取出当前连接的wifi名称,这个就涉及到对文本内容的提取了
需求
1、实现找到文本中特定的内容,并提取出赋值使用的shell脚本
2、在C语言代码中实现查找当前连接wifi的名称
需求1实现及使用示例
测试的文本(test_file.txt):
this is test
test name:"123"456/789%"
test author:"a man"
bash的实现(test_1.sh):查找“name:”之后的字符串,且不包含双引号
#!/bin/bash
find_str="name:"
str=`cat ./test_file.txt|grep ${find_str}`
str=${str#*${find_str}}
str=${str:1:-1}
echo str:$str
在终端运行test_1.sh,显示结果如下
ubuntu@ubuntu:~/my_test_code/test_sh_change_str$ ./test_1.sh
str:123"456/789%
脚本说明:
str=${str#*${find_str}}
表示从 str 字符串第一次出现 f i n d s t r 变量指定的字符串的位置开始,截取 {find_str}变量指定的字符串的位置开始,截取 findstr变量指定的字符串的位置开始,截取{find_str}变量右边的所有字符
str=${str:1:-1}
表示从 str 字符串的右边第 1 个字符开始,向右截取到 倒数第1 个字符
需求2实现及使用示例
c语言中调用shell命令并获得shell命令输出的结果就需要 popen() 函数和 pclose() 函数了;
popen和 pclose 说明:
popen是进程I/O函数,与pclose函数一起使用,功能是通过创建一个管道,调用 fork 产生一个子进程,执行一个 shell 以运行命令来开启一个进程。
popen和 pclose 头文件:
#include <stdio.h>
popen和 pclose 函数定义:
FILE * popen ( const char * command , const char * type );
int pclose ( FILE * stream );
传入参数:
command 参数是一个指向以 NULL 结束的 shell 命令字符串的指针。这行命令将被传到 bin/sh 并使用-c 标志,shell 将执行这个命令
注意这个command是以bin/sh执行的,和bin/bash还是有一些区别的
type 参数只能是读或者写中的一种,得到的返回值(标准 I/O 流)也具有和 type 相应的只读或只写类型。如果 type 是 “r” 则文件指针连接到 command 的标准输出;如果 type 是 “w” 则文件指针连接到 command 的标准输入
返回值:
popen 没有为内存分配失败设置 errno 值。如果调用 fork() 或 pipe() 时出现错误,errno 被设为相应的错误类型。如果 type 参数不合法,errno将返回EINVAL
实现示例:
#include <stdio.h>
#define _LINE_LENGTH 300
int main(int argc , char* argv[])
{
FILE *file;
char line[_LINE_LENGTH];
file = popen("str=`iwconfig wlan0|grep ESSID`; str=${str#*ESSID:}; str_len=${#str}; str_len=`expr ${str_len} - 4`; str=${str:1:${str_len}}; echo $str", "r");
if (NULL != file)
{
// while (fscanf(file, "%[^\n]", line) != 0)
while (fgets(line, _LINE_LENGTH, file) != NULL)
{
printf("line=%s\n", line);
}
}
else
{
return 1;
}
pclose(file);
return 0;
}
执行此程序的结果:
[root@board:/]# ./test_app_V0.0.1
line=Home Wifi
实现说明:
1、shell脚本:
str=`iwconfig wlan0|grep ESSID`; str=${str#*ESSID:}; str_len=${#str}; str_len=`expr ${str_len} - 4`; str=${str:1:${str_len}}; echo $str
这个主要是多个shell脚本写在同一行的实现,拆分如下
# 获取当前wifi连接信息,并查找到带wifi名称(ESSID)的行赋值给str
str=`iwconfig wlan0|grep ESSID`;
# 截取字符串str的内容,只取ESSID:右边的值
str=${str#*ESSID:};
# 获取字符串str的长度
str_len=${#str};
# 去除\r\n等隐藏的后缀
str_len=`expr ${str_len} - 4`;
# 截取字符串的第一个字符到倒数第4个字符
str=${str:1:${str_len}};
# 输出字符
echo $str
2、fscanf 函数使用的正则表达式:
%[^\n]
这个表示读取字符串,直到遇到\n才结束
拓展1:
%[^\"]
这个表示读取字符串,直到遇到双引号才结束,斜杆为转义出双引号
拓展2:
\"%[^\"]
这个表示过滤字符串的第一个双引号,读取到第二个双引号才结束
总结
字符串的截取主要还是根据长度,或者是特殊字符进行定位截取,所以还是需要根据实际场景分析,选择合适的截取方式。
免责声明:本文内容含网络参考、作者编写等,内容版权归原作者所有,未经允许,禁止转载。如涉及作品版权问题,请与我们联系,我们将根据您提供的版权证明材料确认版权并支付稿酬或者删除内容。