txt批处理提取txt第一行目标字符行

38309人阅读
C++中Txt文件读取和写入
一、ASCII 输出
为了使用下面的方法, 你必须包含头文件&fstream.h&(译者注:在标准C++中,已经使用&fstream&取代& fstream.h&,所有的C++标准头文件都是无后缀的。)。这是 &iostream.h&的一个扩展集, 提供有缓冲的文件输入输出操作. 事实上, &iostream.h& 已经被&fstream.h&包含了, 所以你不必包含所有这两个文件, 如果你想显式包含他们,那随便你。我们从文件操作类的设计开始, 我会讲解如何进行ASCII I/O操作。如果你猜是&fstream,& 恭喜你答对了!
但这篇文章介绍的方法,我们分别使用&ifstream&?和 &ofstream& 来作输入输出。
如果你用过标准控制台流&cin&?和 &cout,& 那现在的事情对你来说很简单。 我们现在开始讲输出部分,首先声明一个类对象。
这就可以了,不过你要打开一个文件的话, 必须像这样调用ofstream::open()。
fout.open(&output.txt&); 你也可以把文件名作为构造参数来打开一个文件.
ofstream fout(&output.txt&); 这是我们使用的方法, 因为这样创建和打开一个文件看起来更简单. 顺便说一句, 如果你要打开的文件不存在,它会为你创建一个, 所以不用担心文件创建的问题. 现在就输出到文件,看起来和&cout&的操作很像。对不了解控制台输出&cout&的人, 这里有个例子。
int num = 150;
char name[] = &John Doe&;
fout && &Here is a number: & && num && &/n&;
fout && &Now here is a string: & && name && &/n&; 现在保存文件,你必须关闭文件,或者回写文件缓冲. 文件关闭之后就不能再操作了, 所以只有在你不再操作这个文件的时候才调用它,它会自动保存文件。回写缓冲区会在保持文件打开的情况下保存文件, 所以只要有必要就使用它。 回写看起来像另一次输出, 然后调用方法关闭。像这样:
fout && fout.close(); 现在你用文本编辑器打开文件,内容看起来是这样:
Here is a number: 150 Now here is a string: John Doe 很简单吧! 现在继续文件输入, 需要一点技巧, 所以先确认你已经明白了流操作,对 &&&& 和&&&& 比较熟悉了, 因为你接下来还要用到他们。继续…
二、ASCII 输入
输入和&cin& 流很像. 和刚刚讨论的输出流很像, 但你要考虑几件事情。在我们开始复杂的内容之前, 先看一个文本:
12 GameDev 15.45 L This is really awesome! 为了打开这个文件,你必须创建一个in-stream对象,?像这样。
ifstream fin(&input.txt&); 现在读入前四行. 你还记得怎么用&&&& 操作符往流里插入变量和符号吧?好,?在 &&&& (插入)?操作符之后,是&&&& (提取) 操作符. 使用方法是一样的. 看这个代码片段.
char letter, word[8];
fin && fin && fin && fin && 也可以把这四行读取文件的代码写为更简单的一行。
fin && number && word && real && 它是如何运作的呢? 文件的每个空白之后, &&&& 操作符会停止读取内容, 直到遇到另一个&&操作符. 因为我们读取的每一行都被换行符分割开(是空白字符), &&&& 操作符只把这一行的内容读入变量。这就是这个代码也能正常工作的原因。但是,可别忘了文件的最后一行。
This is really awesome! 如果你想把整行读入一个char数组, 我们没办法用&&&&?操作符,因为每个单词之间的空格(空白字符)会中止文件的读取。为了验证:
char sentence[101]; fin && 我们想包含整个句子, &This is really awesome!& 但是因为空白, 现在它只包含了&This&. 很明显, 肯定有读取整行的方法, 它就是getline()。这就是我们要做的。
fin.getline(sentence, 100); 这是函数参数. 第一个参数显然是用来接受的char数组. 第二个参数是在遇到换行符之前,数组允许接受的最大元素数量. 现在我们得到了想要的结果:“This is really awesome!”。
你应该已经知道如何读取和写入ASCII文件了。但我们还不能罢休,因为二进制文件还在等着我们。
三、二进制 输入输出
二进制文件会复杂一点, 但还是很简单的。 首先你要注意我们不再使用插入和提取操作符(译者注:&& 和 && 操作符). 你可以这么做,但它不会用二进制方式读写。你必须使用read() 和write() 方法读取和写入二进制文件. 创建一个二进制文件, 看下一行。
ofstream fout(&file.dat&, ios::binary); 这会以二进制方式打开文件, 而不是默认的ASCII模式。首先从写入文件开始。函数write() 有两个参数。 第一个是指向对象的char类型的指针, 第二个是对象的大小(译者注:字节数)。 为了说明,看例子。
int number = 30; fout.write((char *)(&number), sizeof(number)); 第一个参数写做&(char *)(&number)&. 这是把一个整型变量转为char *指针。如果你不理解,可以立刻翻阅C++的书籍,如果有必要的话。第二个参数写作&sizeof(number)&. sizeof() 返回对象大小的字节数. 就是这样!
二进制文件最好的地方是可以在一行把一个结构写入文件。 如果说,你的结构有12个不同的成员。 用ASCII?文件,你不得不每次一条的写入所有成员。 但二进制文件替你做好了。 看这个。
struct OBJECT { }
obj.number = 15;
obj.letter = ‘M’;
fout.write((char *)(&obj), sizeof(obj)); 这样就写入了整个结构! 接下来是输入. 输入也很简单,因为read()?函数的参数和 write()是完全一样的, 使用方法也相同。
ifstream fin(&file.dat&, ios::binary); fin.read((char *)(&obj), sizeof(obj)); 我不多解释用法, 因为它和write()是完全相同的。二进制文件比ASCII文件简单, 但有个缺点是无法用文本编辑器编辑。 接着, 我解释一下ifstream 和ofstream 对象的其他一些方法作为结束.
四、更多方法
我已经解释了ASCII文件和二进制文件, 这里是一些没有提及的底层方法。
你已经学会了open() 和close() 方法, 不过这里还有其它你可能用到的方法。
方法good() 返回一个布尔值,表示文件打开是否正确。
类似的,bad() 返回一个布尔值表示文件打开是否错误。 如果出错,就不要继续进一步的操作了。
最后一个检查的方法是fail(), 和bad()有点相似, 但没那么严重。
方法get() 每次返回一个字符。
方法ignore(int,char) 跳过一定数量的某个字符, 但你必须传给它两个参数。第一个是需要跳过的字符数。 第二个是一个字符, 当遇到的时候就会停止。 例子,
fin.ignore(100, ‘/n’); 会跳过100个字符,或者不足100的时候,跳过所有之前的字符,包括 ‘/n’。
方法peek() 返回文件中的下一个字符, 但并不实际读取它。所以如果你用peek() 查看下一个字符, 用get() 在peek()之后读取,会得到同一个字符, 然后移动文件计数器。
方法putback(char) 输入字符, 一次一个, 到流中。我没有见到过它的使用,但这个函数确实存在。
只有一个你可能会关注的方法.?那就是 put(char), 它每次向输出流中写入一个字符。
当我们用这样的语法打开二进制文件:
ofstream fout(&file.dat&, ios::binary); &ios::binary&是你提供的打开选项的额外标志. 默认的, 文件以ASCII方式打开, 不存在则创建, 存在就覆盖. 这里有些额外的标志用来改变选项。
ios::app 添加到文件尾
ios::ate 把文件标志放在末尾而非起始。
ios::trunc 默认. 截断并覆写文件。
ios::nocreate 文件不存在也不创建。
ios::noreplace 文件存在则失败。
我用过的唯一一个状态函数是eof(), 它返回是否标志已经到了文件末尾。 我主要用在循环中。 例如, 这个代码断统计小写‘e’ 在文件中出现的次数。
ifstream fin(&file.txt&);
while (!fin.eof()) {
ch = fin.get();
if (ch == ‘e’) counter++;
fin.close(); 我从未用过这里没有提到的其他方法。 还有很多方法,但是他们很少被使用。参考C++书籍或者文件流的帮助文档来了解其他的方法。
你应该已经掌握了如何使用ASCII文件和二进制文件。有很多方法可以帮你实现输入输出,尽管很少有人使用他们。我知道很多人不熟悉文件I/O操作,我希望这篇文章对你有所帮助。 每个人都应该知道. 文件I/O还有很多显而易见的方法,?例如包含文件 &stdio.h&. 我更喜欢用流是因为他们更简单。 祝所有读了这篇文章的人好运, 也许以后我还会为你们写些东西
笔记:C++文件的读取和写入
#include &iostream&
#include &iomanip&
#include &fstream&
int main(){
char buffer[256];
ifstream myfile (&c:\\a.txt&);
ofstream outfile(&c:\\b.txt&);
if(!myfile){
& cout && &Unable to open myfile&;
&&&&&&& exit(1); // terminate with error
if(!outfile){
&&& cout && &Unable to open otfile&;
&&&&&&& exit(1); // terminate with error
int i=0,j=0;
int data[6][2];
& while (! myfile.eof() )
&&& myfile.getline (buffer,10);
&&& sscanf(buffer,&%d %d&,&a,&b);
&&& cout&&a&&& &&&b&&
&&& data[i][0]=a;
&&& data[i][1]=b;
&&& i++;
myfile.close();
for(int k=0;k&i;k++)
&&&& outfile&&data[k][0] &&& &&&data[k][1]&&
&&&& cout&&data[k][0] &&& &&&data[k][1]&&
outfile.close();
无论读写都要包含&fstream&头文件
读:从外部文件中将数据读到程序中来处理
对于程序来说,是从外部读入数据,因此定义输入流,即定义输入流对象:ifsteam infile,infile就是输入流对象。
这个对象当中存放即将从文件读入的数据流。假设有名字为myfile.txt的文件,存有两行数字数据,具体方法:
infile.open(&myfile.txt&);&&&&& //注意文件的路径
infile&&a&&b;&&&&&&&&&&&&&&&&&& //两行数据可以连续读出到变量里
infile.close()
如果是个很大的多行存储的文本型文件可以这么读:
char buf[1024];&&&&&&&&&&&&&&& //临时保存读取出来的文件内容
infile.open(&myfile.js&);
if(infile.is_open())&&&&&&&&& //文件打开成功,说明曾经写入过东西
&while(infile.good() && !infile.eof())
&& memset(buf,0,1024);
&& infile.getline(buf,1204);
&& message =
&& ......&&&&&&&&&&&&&&&&&&&& //这里可能对message做一些操作
&& cout&&message&&
&infile.close();
写:将程序中处理后的数据写到文件当中
对程序来说是将数据写出去,即数据离开程序,因此定义输出流对象ofstream outfile,outfile就是输出流对象,这个对象用来存放将要写到文件当中的数据。具体做法:
outfile.open(&myfile.bat&);& //myfile.bat是存放数据的文件名
if(outfile.is_open())
& outfile&&message&&&&& //message是程序中处理的数据
& outfile.close();
& cout&&&不能打开文件!&&&
c++对文件的读写操作的例子
/*/从键盘读入一行字符,把其中的字母依次放在磁盘文件fa2.dat中,再把它从磁盘文件读入程序,
将其中的小写字母改成大写字母,再存入磁盘fa3.dat中*/
#i nclude&fstream&
#i nclude&iostream&
#i nclude&cmath&
&//////////////从键盘上读取字符的函数
&void read_save(){
&&&&& char c[80];
&&&&& ofstream outfile(&f1.dat&);//以输出方式打开文件
&&&&& if(!outfile){
&&&&&&&&&&&&&&&&&& cerr&&&open error!&&&//注意是用的是cerr
&&&&&&&&&&&&&&&&&& exit(1);
&&&&&&&&&&&&&&&&&& }
&&&&&&&&& cin.getline(c,80);//从键盘读入一行字符
&&&&&&&&& for(int i=0;c[i]!=0;i++) //对字符一个一个的处理,直到遇到'/0'为止
&&&&&&&&&&&&&&& if(c[i]&=65&&c[i]&=90||c[i]&=97&&c[i]&=122){//保证输入的字符是字符
&&&&&&&&&&&&&&&&&& outfile.put(c[i]);//将字母字符存入磁盘文件
&&&&&&&&&&&&&&&&&& cout&&c[i]&&&&;
&&&&&&&&&&&&&&&&&& }
&&&&&&&&&&&&&&&&&& cout&&
&&&&&&&&&&&&&&&&&& outfile.close();
&&&&&&&&&&&&&&&&&& }
&void creat_data(){
&&&&& ifstream infile(&f1.dat&,ios::in);//以输入的方式打开文件
&&&&& if(!infile){
&&&&&&&&&&&&&&&&& cerr&&&open error!&&&
&&&&&&&&&&&&&&&&& exit(1);
&&&&&&&&&&&&&&&&& }
&&& ofstream outfile(&f3.dat&);//定义输出流f3.dat文件
&&& if(!outfile){
&&&&&&&&&&&&&&&& cerr&&&open error!&&&
&&&&&&&&&&&&&&&& exit(1);
&&&&&&&&&&&&&&&& }
&&&& while(infile.get(ch)){//当读取字符成功时
&&&& if(ch&=122&&ch&=97)
&&&& ch=ch-32;
&&&& outfile.put(ch);
&&&& cout&&
&&&& cout&&
&&&& infile.close();
&&&& outfile.close();
&&&& int main(){
&&&&&&&& read_save();
&&&&&&&& creat_data();
&&&&&&& system(&pause&);
&&&&&&&& return 0;
&&&&&&&& }&
一些其他的:
中关于文件的读入和输出转载
中关于文件的读入和输出。
从 文件中读入数据,并输出到中输出的文件中每行之间有一空行相隔
打开输出文件
从 文件中读入数据,并输出到中
其中参参 作用是从指向的文件中
每次读入一行,把数据存到字符串中,从第一行开始
 每读完一行后,系统自动地把指针指向下一行,不用人为
 干预我这里并没有用到字符串
数组,而是只用了一个串
,是因为我每次读入一行
后,立即就把它输出到
中,跟着读下一行
这道题有许多解法的,重要的要了它文件输入输出的原理
 你可以一行行地读入,也可以一个字一个字地读入,或一个词
 一个词地读入,整型或浮点型读入,看你定义的是哪种数据类型不忽略空白,把每行最后那个也读进来。
遇到回车、换行。
输出到文件
输出到屏幕
输出到文件
输出到屏幕
同样的原理,从文件中读入单个字符,每次读入一个后,
  系统自动地把指针指向下一个字,而不用你指定这次读哪个,
下次读哪个,除非你不想从第一个开始读,比如说:我想从
第个字开始读,或者我想读最后个字。这就需要调用
相应的函数,并指定相应的位置。
主  题:请问中怎么实现读取文件时的行定位就是读取指定的行的内容
请问中怎么实现读取文件时的行定位就是读取指定的行的内容
一行一行的读到你想要的那行。
的方法是读一行。
文件对话框读写文本文件年月日文件对话框读写文本文件读文本文件
显示文件打开对话框
获取文件的绝对路径
写文本文件
显示文件保存对话框
获取文件的绝对路径
文本文件内容我要读一个文件但是我想让一行一行的读而且每行有不一定长度的,应该怎么做呢发表于
看看两次显示的有什么不同。文件如下:
我用怎样才可以写入回车空格而且我要写两栏要对齐回车换行:
如何正确的使用中的参数发表于
问题提出我设计了一个从记事本中读数据的程序。将数据显示在视中。
代码如下:
结果不但在视中没有任何显示,而且记事本中的数据也全部丢失。变成了一片空白。真是搞不懂了。
记事本中的数据是我随便写的。如下:
解决方法在中去掉的意思是没有此文件就建立有了此文件清空文件
最新评论发表评论查看所有评论推荐给好友打印
最好是这样,因为意思是文件即使存在也不清空。发表于
如何使用来读文件发表于
问题提出一数据文件一行一条记录我用一次读一行并对读取的数据做一些处理请问文件还没到结尾文件还没到结尾如何判断如果到了指定位置不读了过一会儿再读又如何做解决方法中不用另加判断条件了因为本身就是判断标志若没有了文件到头返回因此就可程序实现假设你已有了名为的文件在你的工程目录下读两次就不读了记录上次的结果读到哪了接着上回读
这样的命名叫人看了好难受的又是又是我觉得要测试的字符就是就可以了
上面我试了一下,事实并不是如你所说的那样读到空行就停了,而是一直读下去呀!!发表于
我不同意这个回答!
因为返回的条件是遇到文件尾或者一个空行,所以如果说文件的某一条记录后面连续出现了若干条空行,那么函数也会返回,这样文件并没有读取完毕!发表于
删除目录及目录下所有文件与子目录
  ++只提供了删除一个空目录的函数,而在实际应用中往往希望删除其下有很多子目录与文件的目录。为了实现这一功能,我编写了函数,它可以实现这一功能。
函数原型:返回值:成功删除时返回,否则返回参数为要删除的目录名,必须为绝对路径名,如。
函数定义如下:
删除目录失败!警告信息搜集关于按行读取查找特定字符串替换字符串操作
气死了,刚刚误操作,画了一半的表格全都没了。哼哼,没有好兴致说些有趣的话了,爱看不看,爱听不听。气死了!偏偏还要在网页上写,还要不保存!
不说上午的事情了,
直奔主题气死!
关键词:文本文件按行读取查找特定字符串替换字符串
查找:(是类型的)
替换:替换字符串
我用打开一个文件,想查找某一字符串,找到这个字符串后,再读取它对应行的
其他数据,请教大侠指点小弟如何去做,用什么函数。谢谢。
a 过后,逐行读入用判断是否含有特定字符串例子:
你要打开的文件
你要找的字符串
从指定文件中提取指定字符串
读取文件内容
判断是否到了文件最末
未找到找到字符串
获得需要查找的字符串所在行
去掉空白字符
判断是否已经找到需要的字串
获得需要查找的字符串所在列
判断是否需要提取字符串
判断提取字符串的规则,如果为-,则不论字串在任何位置,都可以
进行提取;否则,字串必须在指定位置时才可以提取
未找到找到字符串
其中是我新建的类,函数声明为
这个函数能实现在指定文本格式的文件中进行特定字符串的查找、提取、定位等工作,其中参数初始化为:
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:289131次
积分:3345
积分:3345
排名:第5260名
原创:66篇
转载:99篇
评论:29条
(2)(10)(1)(2)(8)(16)(12)(61)(38)(15)awk执行行操作及怎样从文本文件和字符串中抽取信息(二)-Shell-电脑编程网awk执行行操作及怎样从文本文件和字符串中抽取信息(二)作者:佚名 和相关&&
awk条件操作符awk内置变量 awk操作符内置的字符串函数==========================================================awk条件操作符 操作符描述& 小于& = 大于等于 & = 小于等于== 等于!= 不等于 ~ 匹配!~ 不匹配 1. 匹配 为使一域号匹配正则表达式,使用符号'~'后紧跟正则表达式,也可以用if语句。awk中if后面的条件用()括起来。 观察文件grade.txt,如果只要显示brown腰带级别可知其所在域为field-4,这样可以写出表达式{if($4~/Brown/) print}意即如果field-4包含brown,打印它。如果条件满足,则打印匹配记录行。可以编写下面脚本,因为这是一个动作,必须用花括号{}括起来。代码:[root@Linux_chenwy sam]# awk '{if($4~/Brown/) print }' grade.txt J.Troll 07/99 4842 Brown-3 12 26 26 L.Tansl 05/99 4712 Brown-2 12 30 28匹配记录找到时,如果不特别声明,awk缺省打印整条记录。使用if语句开始有点难,但不要着急,因为有许多方法可以跳过它,并仍保持同样结果。下面例子意即如果记录包含模式brown,就打印它:代码:[root@Linux_chenwy sam]# awk '$4~/Brown/' grade.txt J.Troll 07/99 4842 Brown-3 12 26 26 L.Tansl 05/99 4712 Brown-2 12 30 282. 精确匹配 假定要使字符串精确匹配,比如说查看学生序号48,文件中有许多学生序号包含48,如果在field-3中查询序号48,awk将返回所有序号带48的记录:代码:[root@Linux_chenwy sam]# awk '{if($3~/48/) print}' grade.txt M.Tans 5/99 48311 Green 8 40 44 J.Lulu 06/99 48317 green 9 24 26 P.Bunny 02/99 48 Yellow 12 35 28 J.Troll 07/99 4842 Brown-3 12 26 26 为精确匹配48,使用等号==,并用单引号括起条件。例如$3==&48&代码:[root@Linux_chenwy sam]# awk '$3==&48&' grade.txt P.Bunny 02/99 48 Yellow 12 35 28 [root@Linux_chenwy sam]# awk '{if($3==&48&) print}' grade.txt P.Bunny 02/99 48 Yellow 12 35 283. 不匹配 有时要浏览信息并抽取不匹配操作的记录,与~相反的符号是!~,意即不匹配。像原来使用查询brown腰带级别的匹配操作一样,现在看看不匹配情况。表达式!~/Brown/,意即查询不包含模式brown腰带级别的记录并打印它。 注意,缺省情况下,awk将打印所有匹配记录,因此这里不必加入动作部分。 代码:[root@Linux_chenwy sam]# awk '$4!~/Brown/' grade.txt M.Tans 5/99 48311 Green 8 40 44 J.Lulu 06/99 48317 green 9 24 26 P.Bunny 02/99 48 Yellow 12 35 28可以只对field-4进行不匹配操作,方法如下:代码:[root@Linux_chenwy sam]# awk '{if($4!~/Brown/) print }' grade.txt J.Troll 07/99 4842 Brown-3 12 26 26 L.Tansl 05/99 4712 Brown-2 12 30 28如果只使用命令awk $4!=&brown&{print } grade.txt,将返回错误结果,因为用引号括起了brown,将只匹配‘brown而不匹配brown-2和brown-3,当然,如果想要查询非brown-2的腰带级别,可做如下操作:代码:[root@Linux_chenwy sam]# awk '$4!=&Brown-2& {print }' grade.txt M.Tans 5/99 48311 Green 8 40 44 J.Lulu 06/99 48317 green 9 24 26 P.Bunny 02/99 48 Yellow 12 35 28 J.Troll 07/99 4842 Brown-3 12 26 26 4. 小于 看看哪些学生可以获得升段机会。测试这一点即判断目前级别分field-6是否小于最高分field-7,在输出结果中,加入这一改动很容易。 代码:[root@Linux_chenwy sam]# awk '{if($6&$7) print }' grade.txt M.Tans 5/99 48311 Green 8 40 44 J.Lulu 06/99 48317 green 9 24 265. 小于等于 对比小于,小于等于只在操作符上做些小改动,满足此条件的记录也包括上面例子中的输出情况。 代码:[root@Linux_chenwy sam]# awk '{if($6 &= $7) print $1}' grade.txt M.Tans J.Lulu J.Troll6. 大于 代码:[root@Linux_chenwy sam]# awk '{if($6 & $7) print $1}' grade.txt P.Bunny L.Tansl7. 设置大小写 为查询大小写信息,可使用[ ]符号。在测试正则表达式时提到可匹配[ ]内任意字符或单词,因此若查询文件中级别为green的所有记录,不论其大小写,表达式应为'/[Gg]reen/' 代码:[root@Linux_chenwy sam]# awk '/[Gg]reen/' grade.txt M.Tans 5/99 48311 Green 8 40 44 J.Lulu 06/99 48317 green 9 24 268. 任意字符 抽取名字,其记录第一域的第四个字符是a,使用句点.。表达式/^...a/意为行首前三个字符任意,第四个是a,尖角符号代表行首。 代码:[root@Linux_chenwy sam]# awk '$1 ~ /^...a/' grade.txt M.Tans 5/99 48311 Green 8 40 44 L.Tansl 05/99 4712 Brown-2 12 30 289. 或关系匹配 为抽取级别为yellow或brown的记录,使用竖线符|。意为匹配|两边模式之一。注意,使用竖线符时,语句必须用圆括号括起来。代码:[root@Linux_chenwy sam]# awk '$0 ~/(Yellow|Brown)/' grade.txt P.Bunny 02/99 48 Yellow 12 35 28 J.Troll 07/99 4842 Brown-3 12 26 26 L.Tansl 05/99 4712 Brown-2 12 30 28上面例子输出所有级别为Ye l l o w或B r o w n的记录。 使用这种方法在查询级别为G r e e n或g r e e n时,可以得到与使用[ ]表达式相同的结果。 代码:[root@Linux_chenwy sam]# awk '/^M/' grade.txt M.Tans 5/99 48311 Green 8 40 44 10. 行首 不必总是使用域号。如果查询文本文件行首包含M的代码,可简单使用下面^符号: 代码:[root@Linux_chenwy sam]# awk '/^M/' grade.txt复合表达式即为模式间通过使用下述各表达式互相结合起来的表达式: 引用:&& AND : 语句两边必须同时匹配为真。 || O R:语句两边同时或其中一边匹配为真。 ! 非求逆11. AND 打印记录,使其名字为‘P.Bunny且级别为Yellow,使用表达式($1==&P.Bunny& && $4==&Yellow& ),意为&&两边匹配均为真。完整命令如下: 代码:[root@Linux_chenwy sam]# awk '{if ($1==&P.Bunny& && $4==&Yellow&) print $0}' grade.txt P.Bunny 02/99 48 Yellow 12 35 2812. Or 如果查询级别为Yellow或Brown,使用或命令。意为&||&符号两边的匹配模式之一或全部为真。代码:[root@Linux_chenwy sam]# awk '{if ($4==&Yellow& || $4~/Brown/) print $0}' grade.txt P.Bunny 02/99 48 Yellow 12 35 28 J.Troll 07/99 4842 Brown-3 12 26 26 L.Tansl 05/99 4712 Brown-2 12 30 28原来不一定得加print,下面我自己对例一二做了一下 代码:1 [root@Linux_chenwy sam]# awk '$4~/Brown/' grade.txt J.Troll 07/99 4842 Brown-3 12 26 26 L.Tansl 05/99 4712 Brown-2 12 30 28代码:2 [root@Linux_chenwy sam]# awk '$3==&48&' grade.txt P.Bunny 02/99 48 Yellow 12 35 28代码:[root@Linux_chenwy sam]# awk '$3=&48&' grade.txt M.Tans 5/99 48 Green 8 40 44 J.Lulu 06/99 48 green 9 24 26 P.Bunny 02/99 48 Yellow 12 35 28 J.Troll 07/99 48 Brown-3 12 26 26 L.Tansl 05/99 48 Brown-2 12 30 282中,我把=和==写错了,呵呵,一个是赋值,一个是等于awk内置变量 awk有许多内置变量用来设置环境信息。这些变量可以被改变。表9-3显示了最常使用的一些变量,并给出其基本含义。 引用:awk内置变量 ARGC 命令行参数个数 ARGV 命令行参数排列 ENVIRON 支持队列中系统环境变量的使用 FILENAME awk浏览的文件名 FNR 浏览文件的记录数 FS 设置输入域分隔符,等价于命令行- F选项 NF 浏览记录的域个数 NR 已读的记录数 OFS 输出域分隔符 ORS 输出记录分隔符 RS 控制记录分隔符 引用:A R G C支持命令行中传入a w k脚本的参数个数。A R G V是A R G C的参数排列数组,其中每一元素表示为A R G V [ n ],n为期望访问的命令行参数。 E N V I R O N 支持系统设置的环境变量,要访问单独变量,使用实际变量名,例如E N V I R O N [“E D I TO R”] =“Vi”。 F I L E N A M E支持a w k脚本实际操作的输入文件。因为a w k可以同时处理许多文件,因此如果访问了这个变量,将告之系统目前正在浏览的实际文件。 F N R支持a w k目前操作的记录数。其变量值小于等于N R。如果脚本正在访问许多文件,每一新输入文件都将重新设置此变量。 F S用来在a w k中设置域分隔符,与命令行中- F选项功能相同。缺省情况下为空格。如果用逗号来作域分隔符,设置F S = &,&。 N F支持记录域个数,在记录被读之后再设置。 O F S允许指定输出域分隔符,缺省为空格。如果想设置为#,写入O F S = & # &。 O R S为输出记录分隔符,缺省为新行(
n)。 R S是记录分隔符,缺省为新行(
n )。NF、NR和FILENAME 要快速查看记录个数,应使用N R。比如说导出一个文件后,如果想快速浏览记录个数,以便对比于其初始状态,查出导出过程中出现的错误。使用N R将打印输入文件的记录个数。print NR放在E N D语法中。 代码:[root@chenwy sam]# awk 'END{print NR}' grade.txt 5如:所有学生记录被打印,并带有其记录号。使用N F变量显示每一条读记录中有多少个域,并在E N D部分打印输入文件名。 [root@chenwy sam]# awk '{print NF,NR,$0} END{print FILENAME}' grade.txt 代码:7 1 M.Tans 5/99 48311 Green 8 40 44 7 2 J.Lulu 06/99 48317 green 9 24 26 7 3 P.Bunny 02/99 48 Yellow 12 35 28 7 4 J.Troll 07/99 4842 Brown-3 12 26 26 7 5 L.Tansl 05/99& & & &4712 Brown-2 12 30 28 grade.txt在从文件中抽取信息时,最好首先检查文件中是否有记录。下面的例子只有在文件中至少有一个记录时才查询B r o w n级别记录。使用A N D复合语句实现这一功能。意即至少存在一个记录后,查询字符串B r o w n,最后打印结果。 代码:[root@chenwy sam]# awk '{if (NR&0 && $4~/Brown/)print $0}' grade.txt J.Troll 07/99 4842 Brown-3 12 26 26 L.Tansl 05/99& &4712 Brown-2 12 30 28N F的一个强大功能是将变量$ P W D的返回值传入a w k并显示其目录。这里需要指定域分隔符/。 代码:[root@chenwy sam]# echo $PWD | awk -F/ ' {print $NF}' sam另一个例子是显示文件名。 代码:[root@chenwy sam]# echo &/usr/local/etc/rc.sybase& | awk -F/ '{print $NF}' rc.sybase如果不指定域分割符,返回的如下: 代码:[root@chenwy sam]# echo $PWD | awk& '{print $NF}' /usr/sam [root@chenwy sam]# echo &/usr/local/etc/rc.sybase& | awk '{print $NF}' /usr/local/etc/rc.sybaseawk操作符 在a w k中使用操作符,基本表达式可以划分为数字型、字符串型、变量型、域及数组元素,前面已经讲过一些。下面列出其完整列表。 在表达式中可以使用下述任何一种操作符。 引用:= += *= / = %= ^ = 赋值操作符 ? 条件表达操作符 || && ! 并、与、非(上一节已讲到) ~!~ 匹配操作符,包括匹配和不匹配 & &= == != && 关系操作符 + - * / % ^ 算术操作符 + + -- 前缀和后缀前面已经讲到了其中几种操作,下面继续讲述未涉及的部分。 1. 设置输入域到域变量名 在a w k中,设置有意义的域名是一种好习惯,在进行模式匹配或关系操作时更容易理解。 一般的变量名设置方式为n a m e = $ n,这里n a m e为调用的域变量名, n为实际域号。例如设置学生域名为n a m e,级别域名为b e l t,操作为n a m e = $ 1 ; b e l t s = $ 4。注意分号的使用,它分隔a w k命令。下面例子中,重新赋值学生名域为n a m e,级别域为b e l t s。查询级别为Ye l l o w的记录,并最终打印名称和级别。 代码:[sam@chenwy sam]$ awk '{name=$1;belts=$4;if(belts ~/Yellow/) print name& is belt &belts}' grade.txt P.Bunny is belt Yellow2. 域值比较操作 有两种方式测试一数值域是否小于另一数值域。 1) 在B E G I N中给变量名赋值。 2) 在关系操作中使用实际数值。 通常在B E G I N部分赋值是很有益的,可以在a w k表达式进行改动时减少很多麻烦。 使用关系操作必须用圆括号括起来。 下面的例子查询所有比赛中得分在2 7点以下的学生。 用引号将数字引用起来是可选的,“2 7”、2 7产生同样的结果。 代码:[sam@chenwy sam]$ awk '{if ($6&$7) print $0}' grade.txt M.Tans 5/99 48311 Green 8 40 44 J.Lulu 06/99 48317 green 9 24 26第二个例子中给数字赋以变量名B A S E L I N E和在B E G I N部分给变量赋值,两者意义相同。 代码:[sam@chenwy sam]$ awk 'BEGIN{BASELINE=&27&} {if ($6<baseline) J.Lulu 06/99 48317 green 9 24 26 J.Troll 07/99 4842 Brown-3 12 26 263. 修改数值域取值 当在a w k中修改任何域时,重要的一点是要记住实际输入文件是不可修改的,修改的只是保存在缓存里的a w k复本。a w k会在变量N R或N F变量中反映出修改痕迹。 为修改数值域,简单的给域标识重赋新值,如: $ 1 = $ 1 + 5,会将域1数值加5,但要确保赋值域其子集为数值型。 修改M . Ta n s l e y的目前级别分域,使其数值从4 0减为3 9,使用赋值语句$ 6 = $ 6 - 1,当然在实施修改前首先要匹配域名。 代码:[sam@chenwy sam]$ awk '{if($1==&M.Tans&) {$6=$6-1};print $1,$6,$7}' grade.txt M.Tans 39 44 J.Lulu 24 26 P.Bunny 35 28 J.Troll 26 26 L.Tansl 30 28代码:[sam@chenwy sam]$ awk '{if($1==&M.Tans&) {$6=$6-1;print $1,$6,$7}}' grade.txt M.Tans 39 444. 修改文本域 修改文本域即对其重新赋值。需要做的就是赋给一个新的字符串。在J . Tr o l l中加入字母,使其成为J . L . Tr o l l,表达式为$ 1 = & J . L . Tr o l l &,记住字符串要使用双秒号( & &),并用圆括号括起整个语法。 代码:[sam@chenwy sam]$ awk '{if($1==&J.Troll&) $1=&J.L.Troll&; print $1}' grade.txt M.Tans J.Lulu P.Bunny J.L.Troll L.Tansl5. 只显示修改记录 上述例子均是对一个小文件的域进行修改,因此打印出所有记录查看修改部分不成问题,但如果文件很大,记录甚至超过1 0 0,打印所有记录只为查看修改部分显然不合情理。在模式后面使用花括号将只打印修改部分。取得模式,再根据模式结果实施操作,可能有些抽象,现举一例,只打印修改部分。注意花括号的位置。 代码:[sam@chenwy sam]$ awk '{if($1==&J.Troll&) {$1=&J.L.Troll&; print $1}}' grade.txt& J.L.Troll不知道为什么,我这里多了一个空行? 6. 创建新的输出域 在a w k中处理数据时,基于各域进行计算时创建新域是一种好习惯。创建新域要通过其他域赋予新域标识符。如创建一个基于其他域的加法新域{ $ 4 = $ 2 + $ 3 },这里假定记录包含3个域,则域4为新建域,保存域2和域3相加结果。 在文件g r a d e . t x t中创建新域8保存域目前级别分与域最高级别分的减法值。表达式为‘{ $ 8 = $ 7 - $ 6 }’,语法首先测试域目前级别分小于域最高级别分。新域因此只打印其值大于零的学生名称及其新域值。在B E G I N部分加入t a b键以对齐报告头。 代码:[sam@chenwy sam]$ awk 'BEGIN{print &Name Difference&}{if($6&$7) {$8=$7-$6;print $1,$8}}' grade.txt Name& & Difference M.Tans 4 J.Lulu 2当然可以创建新域,并赋给其更有意义的变量名。例如: 代码:[sam@chenwy sam]$ awk 'BEGIN{print &Name Difference&}{if($6&$7) {diff=$7-$6;print $1,diff}}' grade.txt Name& & Difference M.Tans 4 J.Lulu 27. 增加列值 为增加列数或进行运行结果统计,使用符号+ =。增加的结果赋给符号左边变量值,增加到变量的域在符号右边。例如将$ 1加入变量t o t a l,表达式为t o t a l + = $ 1。列值增加很有用。许多文件都要求统计总数,但输出其统计结果十分繁琐。在a w k中这很简单,请看下面的例子。 将所有学生的‘目前级别分’加在一起,方法是t o t + = $ 6,t o t即为a w k浏览的整个文件的域6结果总和。所有记录读完后,在E N D部分加入一些提示信息及域6总和。不必在a w k中显示说明打印所有记录,每一个操作匹配时,这是缺省动作。 代码:[sam@chenwy sam]$ awk '(tot+=$6); END{print &Club student total points :& tot}' grade.txt M.Tans 5/99 48311 Green 8 40 44 J.Lulu 06/99 48317 green 9 24 26 P.Bunny 02/99 48 Yellow 12 35 28 J.Troll 07/99 4842 Brown-3 12 26 26 L.Tansl 05/99 4712 Brown-2 12 30 28 Club student total points :155如果文件很大,你只想打印结果部分而不是所有记录,在语句的外面加上圆括号()即可。 代码:[sam@chenwy sam]$ awk '{(tot+=$6)}; END{print &Club student total points :& tot}' grade.txt Club student total points :1558. 文件长度相加 在目录中查看文件时,如果想快速查看所有文件的长度及其总和,但要排除子目录,使用ls -l命令,然后管道输出到a w k,a w k首先剔除首字符为d(使用正则表达式)的记录,然后将文件长度列相加,并输出每一文件长度及在E N D部分输出所有文件的长度。 本例中,首先用ls -l命令查看一下文件属性。注意第二个文件属性首字符为d,说明它是一个目录,文件长度是第5列,文件名是第9列。如果系统不是这样排列文件名及其长度,应适时加以改变。 下面的正则表达式表明必须匹配行首,并排除字符d,表达式为^ [ ^ d ]。 使用此模式打印文件名及其长度,然后将各长度相加放入变量t o t中。 代码:[sam@chenwy sam]$ ls -l | awk '/^[^d]/ {print $9& &$5} {tot+=$5} END {print &total KB:& tot}' ................... total KB:174144内置的字符串函数 代码:awk内置字符串函数 g s u b ( r, s ) 在整个$ 0中用s替代r g s u b ( r, s , t ) 在整个t中用s替代r i n d e x ( s , t ) 返回s中字符串t的第一位置 l e n g t h ( s ) 返回s长度 m a t c h ( s , r ) 测试s是否包含匹配r的字符串 s p l i t ( s , a , f s ) 在f s上将s分成序列a s p r i n t ( f m t , e x p ) 返回经f m t格式化后的e x p s u b ( r, s ) 用$ 0中最左边最长的子串代替s s u b s t r ( s , p ) 返回字符串s中从p开始的后缀部分 s u b s t r ( s , p , n ) 返回字符串s中从p开始长度为n的后缀部分g s u b函数有点类似于s e d查找和替换。它允许替换一个字符串或字符为另一个字符串或字符,并以正则表达式的形式执行。第一个函数作用于记录$ 0,第二个g s u b函数允许指定目标,然而,如果未指定目标,缺省为$ 0。 i n d e x(s,t)函数返回目标字符串s中查询字符串t的首位置。l e n g t h函数返回字符串s字符长度。 m a t c h函数测试字符串s是否包含一个正则表达式r定义的匹配。s p l i t使用域分隔符f s将字符串s划分为指定序列a。 s p r i n t函数类似于p r i n t f函数(以后涉及),返回基本输出格式f m t的结果字符串e x p。 s u b(r,s)函数将用s替代$ 0中最左边最长的子串,该子串被( r)匹配。 s u b(s,p)返回字符串s在位置p后的后缀。s u b s t r(s,p,n)同上,并指定子串长度为n。 现在看一看a w k中这些字符串函数的功能。 1. gsub 要在整个记录中替换一个字符串为另一个,使用正则表达式格式, /目标模式/,替换模式/。例如改变学生序号4 8 4 2到4 8 9 9: 代码:[root@Linux_chenwy root]# cd /usr/sam [root@Linux_chenwy sam]# awk 'gsub(/){print $0}' grade.txt J.Troll 07/99 4899 Brown-3 12 26 26代码:[root@Linux_chenwy sam]# awk 'gsub(/)' grade.txt J.Troll 07/99 4899 Brown-3 12 26 262. index 查询字符串s中t出现的第一位置。必须用双引号将字符串括起来。例如返回目标字符串B u n n y中n y出现的第一位置,即字符个数。 代码:[root@Linux_chenwy sam]# awk 'BEGIN {print index(&Bunny&,&ny&)}' grade.txt 43. length 返回所需字符串长度,例如检验字符串J . Tr o l l返回名字及其长度,即人名构成的字符个数 代码:[root@Linux_chenwy sam]# awk '$1==&J.Troll& {print length($1)& &$1}' grade.txt 7 J.Troll还有一种方法,这里字符串加双引号。 代码:[root@Linux_chenwy sam]# awk 'BEGIN{print length(&A FEW GOOD MEN&)}' 144. match m a t c h测试目标字符串是否包含查找字符的一部分。可以对查找部分使用正则表达式,返回值为成功出现的字符排列数。如果未找到,返回0,第一个例子在A N C D中查找d。因其不存在,所以返回0。第二个例子在A N C D中查找D。因其存在,所以返回A N C D中D出现的首位置字符数。第三个例子在学生J . L u l u中查找u。 代码:[root@Linux_chenwy sam]# awk 'BEGIN{print match(&ANCD&,/d/)}' 0 [root@Linux_chenwy sam]# awk 'BEGIN{print match(&ANCD&,/D/)}' 4 [root@Linux_chenwy sam]# awk '$1==&J.Lulu& {print match($1,&u&)}' grade.txt 45. split 使用s p l i t返回字符串数组元素个数。工作方式如下:如果有一字符串,包含一指定分隔符- ,例如A D2 - K P 9 - J U 2 - L P - 1,将之划分成一个数组。使用s p l i t,指定分隔符及数组名。此例中,命令格式为( & A D 2 - K P 9 - J U 2 - L P - 1 &,p a r t s _ a r r a y,& - &),s p l i t然后返回数组下标数,这里结果为4。 代码:[root@Linux_chenwy sam]# awk 'BEGIN {print split(&123-456-789&,pats_array,&-&)}'3还有一个例子使用不同的分隔符。 代码:[root@Linux_chenwy sam]# awk 'BEGIN {print split(&123#456#789&,myarray,&#&)}'& & & & & & & & & & & & & & & & & & & & & & & & & & & & 3这个例子中,s p l i t返回数组m y a r r a y的下标数。数组m y a r r a y取值如下: 代码:myarray[1]=123 myarray[2]=456 myarray[3]=789结尾部分讲述数组概念。 6. sub 使用s u b发现并替换模式的第一次出现位置。字符串S T R包含‘poped popo pill’,执行下列s u b命令s u b(/ o p /,& o p &,S T R)。模式o p第一次出现时,进行替换操作,返回结果如下:‘pO Ped pope pill’。 如:学生J . Tr o l l的记录有两个值一样,“目前级别分”与“最高级别分”。只改变第一个为2 9,第二个仍为2 4不动,操作命令为s u b(/ 2 6 /,& 2 9 &,$ 0),只替换第一个出现2 4的位置。注意J . Tr o l l记录需存在。 代码:[root@Linux_chenwy sam]# awk '$1==&J.Troll& sub(/26/,&29&,$0)' grade.txt M.Tans 5/99 48311 Green 8 40 44 J.Lulu 06/99 48317 green 9 24 29 P.Bunny 02/99 48 Yellow 12 35 28 J.Troll 07/99 4842 Brown-3 12 29 26 L.Tansl 05/99 4712 Brown-2 12 30 287. substr s u b s t r是一个很有用的函数。它按照起始位置及长度返回字符串的一部分。例子如下: 代码:[root@Linux_chenwy sam]# awk '$1==&L.Tansl& {print substr($1,1,3)}' grade.txt L.T上面例子中,指定在域1的第一个字符开始,返回其前面5个字符。 如果给定长度值远大于字符串长度, a w k将从起始位置返回所有字符,要抽取L Ta n s l - e y的姓,只需从第3个字符开始返回长度为7。可以输入长度9 9,a w k返回结果相同。 代码:[root@Linux_chenwy sam]# awk '$1==&L.Tansl& {print substr($1,1,99)}' grade.txt L.Tansls u b s t r的另一种形式是返回字符串后缀或指定位置后面字符。这里需要给出指定字符串及其返回字串的起始位置。例如,从文本文件中抽取姓氏,需操作域1,并从第三个字符开始: 代码:[root@Linux_chenwy sam]# awk '{print substr($1,3)}' grade.txt Tans Lulu Bunny Troll Tansl还有一个例子,在B E G I N部分定义字符串,在E N D部分返回从第t个字符开始抽取的子串。 代码:[root@Linux_chenwy sam]# awk 'BEGIN{STR=&A FEW GOOD MEN&}END{print substr(STR,7)}' grade.txt GOOD MEN8. 从s h e l l中向a w k传入字符串 a w k脚本大多只有一行,其中很少是字符串表示的。大多要求在一行内完成a w k脚本,这一点通过将变量传入a w k命令行会变得很容易。现就其基本原理讲 述一些例子。 使用管道将字符串s t a n d - b y传入a w k,返回其长度。 代码:[root@Linux_chenwy sam]# echo &Stand-by& | awk '{print length($0)}' 8设置文件名为一变量,管道输出到a w k,返回不带扩展名的文件名。 代码:[root@Linux_chenwy sam]# STR=&mydoc.txt& [root@Linux_chenwy sam]# echo $STR|awk '{print substr($STR,1,5)}' mydoc设置文件名为一变量,管道输出到a w k,只返回其扩展名。 代码:[root@Linux_chenwy sam]# STR=&mydoc.txt& [root@Linux_chenwy sam]# echo $STR|awk '{print substr($STR,7)}' txt
相关资料:|||||||awk执行行操作及怎样从文本文件和字符串中抽取信息(二)来源网络,如有侵权请告知,即处理!编程Tags:                &                    

我要回帖

更多关于 txt提取 的文章

 

随机推荐