‘壹’ grep命令保留第一行(c语言实现)
Linux中的 grep 是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。特别是在搜索日志、配置文件、过滤时应用非常广泛。
然而这个命令有个美中不足的地方。它和其他命令配合使用时,把第一行的描述信息给过滤掉了。有时我们想要 同时输出的第一行和匹配行 。因为第一行的描述信息有助于我们理解后面每个字段的含义。
比如我们查看和sda有关的文件系统
这里的116G 58G 53G 分别表示什么? 哪个才是剩余空间?
我们希望得到结果是:
Stackoverflow给出的几种方案,grep 配合 sed 和 awk 使用。但我觉得这些方法不够好,于是我用C语言写了一个程序 grep1 。它可以 智能判断标题行 ,输出彩色标题后调用 grep 完成匹配搜索。因为是调用 grep 的,所以 grep 能用的参数这里也可以用。
为什么要强调智能判断标题行呢? 不是所有标题都在第一行,有的命令(netstat)标题在第二行。。。。。
下面给出源码(少于60行),编译后移动到 /usr/local/bin/grep1 ,PATH环境变量一般包含 /usr/local/bin
效果对比:
‘贰’ Linux中关于grep命令的使用和调整 C语言
继续使用管道线后面追加
|
cut
-d
=
-f
2
详情请查阅cut的manpage
摘选一段
CUT(1)
FSF
CUT(1)
NAME
cut
-
在文件的每一行中提取片断
总览
(SYNOPSIS)
../src/cut
[OPTION]...
[FILE]...
描述
(DESCRIPTION)
在
每个文件
FILE
的
各行
中,
把
提取的
片断
显示在
标准输出.
-b,
--bytes=LIST
输出
这些
字节
-c,
--characters=LIST
输出
这些
字符
-d,
--delimiter=DELIM
使用
DELIM
取代
TAB
做
字段(field)
分隔符
-f,
--fields=LIST
输出
这些
字段
-n
(忽略)
-s,
--only-delimited
不显示
没有
分隔符
的
行
--output-delimiter=STRING
使用
STRING
作为
输出分隔符,
缺省
(的
输出分隔符)
为
输入分隔符
--help
显示
帮助信息,
然后
结束
--version
显示
版本信息,
然后
结束
我写了一段,不过我的mplayer似乎没有-endops选项,大小写变幻采用专门的convertstr函数完成
#!/bin/bash
convertstr
()
{
if
[
$1
=
"XVID"
]
;
then
echo
"XviD"
elif
[
$1
=
"DX50"
]
;
then
echo
"dx50"
else
echo
$1
fi
}
FORMAT=$(convertstr
$(mplayer
-identify
-frames
5
-vo
null
$1
2>
/dev/null
|
grep
ID_VIDEO_FORMAT
|
awk
'{printf
$1}'
|
cut
-d
=
-f
2))
echo
"编码格式:$FORMAT"
‘叁’ Linux下获取进程打开的句柄数,用C代码实现
可以通过指令查询当前进程打开了多少句柄,Linux下有exec函数族可以执行指令,把指令写进去就行了。
-查看当前进程打开了多少句柄数
# lsof -n|awk '{print $2}'|sort|uniq -c|sort -nr|more
-根据ID号来查看进程名。
# ps aef|grep ID号
‘肆’ 用C语言如何实现 linux下 grep 命令>
linux 应当是开放系统,也许可以找到源程序。
我曾写过一个有部分 grep 功能 的程序grep_string.c,用于搜同一文件夹 文件内的字符串
若搜到,则显示文件名,行号,行的内容。
程序如下:
/* ======================================================================*
* grep_string.c
* PC DOSprompt tool, partly similar to unix grep:
* grep string files
* where files is the file names used in DIR command
* open a temp file to store the file names in the file
* read each file name and open/grep/close it
* if match the string, print the line number and the line.
* -------------------------------------------------------------
* call ERASE/F grep_str_temp.tmp
* call DIR/B/A-D *
* L_o_o_n_i_e 2000-Nov
* ======================================================================*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define Buff_size 40960
int DEBUG=0;
FILE *fin;
FILE *fout;
FILE *fname;
char namein[72], nameout[72], namelist[72];
char current_dir[72];
char current_file_name[72];
char target_string[64];
int L_dir; /* Length of current_dir\files string */
int L_target; /* Length of searched string */
int L_row; /* Length of the row fgets just got */
int L_filename; /* Length of current file name */
char *buff;
void init();
void message1(char * progname);
void search(char * target_string);
void clean_it(char * buff, int N_size);
main (int argc, char *argv[])
{
char command[200];
int I_file = 0;
if (argc < 3) (void) message1( argv[0] ); /* argc < 3, print usage and exit */
(void) init(); /* alloc buff */
strcpy(namelist,"C:\\temp\\grep_str_temp.tmp");
strcpy(current_dir, argv[2]);
strcpy(target_string, argv[1]);
L_target = strlen(target_string);
if (DEBUG == 1) {
printf("grep \"%s\" %s\n", target_string, current_dir);
printf("the length of target_string is: %d\n",L_target);
};
/* ------------------------------------------------------------*
* get name list and saved in grep_string_temp.tmp
* ------------------------------------------------------------*/
sprintf(command,"DIR/B/A-D %s > %s", current_dir, namelist);
system(command);
if ( (fname = fopen(namelist,"r") ) == NULL ) {
printf("\007Cann't open work file: %s ", namelist);exit(1);
};
while ( fgets( current_file_name, 72, fname) !=NULL ) {
strncpy(namein, current_file_name, strlen(current_file_name) - 1 );
if (DEBUG == 1) {
printf( "\007I will open %s and search \"%s\"\n", namein, target_string);
};
if ( (fin = fopen(namein,"r") ) == NULL ) {
printf("\007Cann't open current file: %s ", namein);
goto the_end_of_loop;
};
(void) search( target_string );
fclose(fin);
the_end_of_loop: ;
(void) clean_it( current_file_name, 72);
(void) clean_it( namein, 72);
}; /* end of main while loop */
fclose(fname);
if (DEBUG == 0 ) {
sprintf(command,"ERASE/F %s", namelist);
system(command);
};
exit(0);
} /* the End of main program */
/* =================================================================*
* init()
* init global
* L_o_o_n_i_e
* =================================================================*/
void init()
{
L_dir = 0;
L_target = 0;
L_row = 0;
L_filename;
buff = (char *) malloc( Buff_size * sizeof (char));
if (!buff) {
printf("\007No enough memory -- Can not alloc the Buff\n");
exit(2);
};
}
void message1 (char * progname)
{
fprintf(stderr, "========================================================\n");
fprintf(stderr, "The prog searchs a string in files\n");
fprintf(stderr, "If found the string then print the line on screen\n");
fprintf(stderr, "search a string in Chinese GB 8bit bytes is allowed\n");
fprintf(stderr, "\007Usage: %s targetstring files\n", progname);
fprintf(stderr, "For example: %s cgi-bin A*.html\n", progname);
fprintf(stderr, "For example: %s ÖDIÄ A*.html\n", progname);
fprintf(stderr, "Limit: maximum line width is %d bytes\n", Buff_size);
fprintf(stderr, "L_o_o_n_i_e 2000-Nov\n");
fprintf(stderr, "========================================================\n");
exit(1);
}
/* =====================================================================*
* search the target string
* L_target == target_string lenth
* LL == the line length
* if L_target >= LL skip the line
* otherwise loop:
i = 0 to LL - L_target
comp (buff[i],atrget_string,L_target)
if find, then output and goto next
* L_o_o_n_i_e
* ========================================================================*/
void search(char * target_string)
{
int i,j,NN;
int LL;
int ii;
int flag_print_name = 0;
NN = 0;
while ( fgets( buff, Buff_size, fin) !=NULL ) {
LL = 0;
LL = strlen(buff);
NN = NN + 1;
ii = LL - L_target;
if (ii < 0 ) goto Lab1;
for (i=0;i<ii;i++) {
if ( strncmp( &buff[i], target_string, L_target) == 0 ) {
if (flag_print_name == 0) {
printf("In %s\n",namein);
flag_print_name = 1;
};
printf("Line: %d: %s\n", NN, buff);
goto Lab1;
};
};
Lab1:;
(void) clean_it( buff, Buff_size);
};
if (DEBUG == 1) printf("%d lines, last row length=%d\n",NN,LL);
}
void clean_it(char * buff, int N_size)
{
int i;
for (i=0; i< N_size; i++) strncpy(&buff[i], "\0",1);
}
‘伍’ 利用c语言实现grep -C功能
显然 c 语言库是没有的 但是你的程序中的有些是可以有库函数完成的 比如找到匹配一个正则的一行是可以的额, 然后再读取上下五行 也不是很难的事情
‘陆’ 用C语言如何实现linux grep命令
肯定要用 strcmp 啦
写个简单的练练还行先学学 《APUE》 吧
源代码下载地址
http://ftp.gnu.org/gnu/grep/grep-2.7.tar.gz