本程序编写于32位win7旗舰版,测试也是在这个系统下,欢迎朋友们提出修改意见。
功能:
显示指定文本文件的最后n行,支持自动读取及手动按回车读取。
格式说明:
tail <fileName> [-b <Number>] [-l <Number>] [-f <Number>]
标志说明:
-b <Number>
从末尾倒数 Number 表示的 512 字节块位置开始读取指定文件(无此参数则默认最后512字节),若要读取大量文本请将此值调大,例如:tail -b 10 filename.txt
-l <Number>
显示末尾Number行(无此参数则默认显示最后30行)
-f <Number>
每隔多少秒自动显示(无此参数则手动按回车显示下一次)
下面是调用例子:
tail -f 1 -b 2 -l 10 t.txt
每一秒自动显示一次(-f 1),最多从末尾读取512*2个字节(-b 2),从这些字节中读取最后10行(-l 10)
tail -b 2 -l 50 t.txt
最多从末尾读取512*2个字节(-b 2),从这些字节中读取最后50行(-l 50),手动按回车显示(省略[-f])
tail -b 2 t.txt
最多从末尾读取512*2个字节(-b 2),从这些字节中读取最后30行(省略[-l Number]默认读取最后30行),手动按回车显示(省略[-f])
#include <windows.h>
#include <iostream>
#include <fstream>
#include <string>
#include <malloc.h>
#include <stdlib.h>
using namespace std;
/**
* 格式说明:
* tail <fileName> [-b <Number>] [-l <Number>] [-f <Number>]
*
* 标志说明:
* -b <Number>
* 从末尾倒数 Number 表示的 512 字节块位置开始读取指定文件(无此参数则默认最后512字节)
* -l <Number>
* 显示末尾Number行(无此参数则默认显示最后30行)
* -f <Number>
* 每隔多少秒自动显示(无此参数则手动按回车显示下一次)
*
* 例:
* tail -f 1 -b 2 -l 10 t.txt
* 每一秒自动显示一次(-f 1),最多从末尾读取512*2个字节(-b 2),从这些字节中读取最后10行(-l 10)
*
* tail -b 2 -l 50 t.txt
* 最多从末尾读取512*2个字节(-b 2),从这些字节中读取最后50行(-l 50),手动按回车显示(省略[-f])
*
* tail -b 2 t.txt
* 最多从末尾读取512*2个字节(-b 2),从这些字节中读取最后30行(省略[-l Number]默认读取最后30行),手动按回车显示(省略[-f])
*/
// 检查字符数组的内容是否是标志
bool isFlag(char * charArr)
{
string temp = charArr;
if(charArr[0] == '-')
{
// 是以减号开头
if(temp!="-b" && temp!="-f" && temp!="-l")
{
// 非法标志
return false;
}
return true;
}
else
return false;
}
// 检查字符数组的内容是否是正整数,不是正整数则返回零
int isNum(char * charArr)
{
try
{
int v = atoi(charArr);
// 将当前参数转整数
if( atoi(charArr) < 1 )
return 0;
return v;
}
catch(...)
{
return 0;
}
}
/**
* 检查参数是否正确
* @param argc 一共有几个参数(从1开始)
* @param arg 用户输入的参数
*
* @return int (1:验证通过|-1:验证失败)
*/
int checkArg(int argc, char ** arg, int * b, int * l, int * f, char ** filename)
{
// 返回值
int ret = 1;
// 前一个参数是否是标志
bool preArgIsFlag = false;
// 是否已经读到文件名
bool readedFileName = false;
// 是否已经读到-b
bool readedB = false;
// 是否已经读到-l
bool readedL = false;
// 是否已经读到-f
bool readedF = false;
// 一维数组下标
int x = 0, v = 0;
string temp, temp1, temp2;
// 按元素个数从1开始循环
for(int i=1; i<argc; i++)
{
temp1 = arg[i];
if(i < argc-1)
{
temp2 = arg[i+1];
}
// 检查当前循环到的是不是最后一个元素
if(i < argc-1) // 如果当前循环到的不是最后一个元素
{
if(isFlag(arg[i])) // 如果当前元素是标志
{
if(!isFlag(arg[i+1])) // 如果下一个元素不是标志
{
// 如果当前元素是标志、下一个元素不是标志
v = isNum(arg[i+1]);
if(v < 1)
return 0;
if(temp1 == "-b")
{
if(readedB) // 如果已经读到-b则返加零
return 0;
*b = v;
readedB = true;
}
else if(temp1 == "-l")
{
if(readedL) // 如果已经读到-l则返加零
return 0;
*l = v;
readedL = true;
}
else if(temp1 == "-f")
{
if(readedF) // 如果已经读到-f则返加零
return 0;
*f = v;
readedF = true;
}else{ // 非法标志
return 0;
}
i++;
}
else // 如果下一个元素是标志
{
return 0;
}
}else{ // 如果当前元素不是标志则认定当前元素是文件名
if(readedFileName) // 如果已经读到文件名则返回零
return 0;
strcpy(*filename, arg[i]); // 修改传入参数中的文件名
readedFileName = true;
}
} // if(i < argc-1) // 如果当前循环到的不是最后一个元素
else // 如果当前循环到的是最后一个元素
{
if(isFlag(arg[i])){ // 如果当前元素是标志
return 0;
}
else // 如果当前元素不是标志
{
if(readedFileName) // 如果已经读到文件名则返回零
return 0;
strcpy(*filename, arg[i]); // 修改传入参数中的文件名
readedFileName = true;
}
}
} // for(int i=1; i<argc; i++)
if(!readedB) // 如果没有读到-b则赋默认值
{
*b = 1;
}
if(!readedL) // 如果没有读到-l则赋默认值
{
*l = 30;
}
if(!readedF) // 如果没有读到-f则赋默认值
{
*f = 0;
}
// 判断是否有文件名
if(!readedFileName)
return 0;
return ret;
}
int main(int argc, char ** argv)
{
//
int b; // 缓冲区大小(是几个512)
int l; // 要末尾读多少行
int f; // 每隔几秒自动显示
char * filename = new char[512];
// 检查参数是否正确
int result = checkArg(argc, argv, &b, &l, &f, &filename);
if(!result)
{
printf("出现错误,请参照以下说明修改命令参数:\n");
printf("格式说明:\n");
printf(" tail <fileName> [-b <Number>] [-l <Number>] [-f <Number>] \n");
printf(" 其中fileName最长512字节\n\n");
printf("标志说明:\n");
printf(" -b <Number>\n");
printf(" 从末尾倒数 Number 表示的 512 字节块位置开始读取指定文件(无此参数则默认最后512字节)\n");
printf(" -l <Number>\n");
printf(" 显示末尾Number行(无此参数则默认显示最后30行)\n");
printf(" -f <Number>\n");
printf(" 每隔多少秒自动显示(无此参数则手动按回车显示下一次)\n\n");
printf("例:\n");
printf(" tail -f 1 -b 2 -l 10 t.txt \n");
printf(" 每一秒自动显示一次(-f 1),最多从末尾读取512*2个字节(-b 2),从这些字节中读取最后10行(-l 10)\n\n");
printf(" tail -b 2 -l 50 t.txt\n");
printf(" 最多从末尾读取512*2个字节(-b 2),从这些字节中读取最后50行(-l 50),手动按回车显示(省略[-f])\n\n");
printf(" tail -b 2 t.txt\n");
printf(" 最多从末尾读取512*2个字节(-b 2),从这些字节中读取最后30行(省略[-l Number]默认读取最后30行),手动按回车显示(省略[-f])\n");
return 1;
}
// 要显示多少行
int showCount = l, showLineCount;
// 文件总大小
int count;
char * charArr;
while(true)
{
showLineCount = showCount;
ifstream ifs;
// 按二进制读取文本
ifs.open (filename, ios::binary);
if(ifs.fail())
{
cout<<"错误:文件不存在。"<<endl;
return 1;
}
// 将文件指针移动到末尾
ifs.seekg (0, ios::end);
// 读取文件总大小
count = ifs.tellg();
// 根据文件总大小计算应该读取多少字节
int shouldReadLength = (count>=512*b)?512*b:count;
// 按指定大小分配内存,加1是为了能在最后添加结束符'\0'
charArr = new char[shouldReadLength+1];
int i;
// 已读取字节数
int readed = 0;
// 将文件指针移动到距末尾-shouldReadLength个字节的位置
ifs.seekg (-shouldReadLength, ios::end);
// 读取指定大小的内容
ifs.read (charArr,shouldReadLength);
// 添加结束符
charArr[shouldReadLength] = '\0';
for(i=shouldReadLength-1; i>=0 && showLineCount>0; i--,readed++)
{
if(charArr[i] == '\n'){
showLineCount--;
}
}
// 输出
printf("%s\n", charArr + shouldReadLength - readed); // 这种方法可以输出到控制台
//cout.write (charArr + shouldReadLength - readed,readed);// 这种方法也可以输出到控制台
// 释放字符数组的内存空间
delete [] charArr;
// 关闭文件流
ifs.close();
if(f==0) // 用户没有输入-f参数,等待用户再次敲回车
{
// 如果用手动的就用cin---------- 开始
cout<<"按Ctrl+C退出或按回车继续:";
// 用户按回车时进行下一次显示
cin.get();
//system("PAUSE");
// 如果用手动的就用cin---------- 结束
}
else // 用户输入了-f参数,按用户输入的秒数睡眠
{
// 如果要自动的就用Sleep-------- 开始
Sleep(1000*f);
// 如果要自动的就用Sleep-------- 结束
}
}
return 0;
}
附件tail.rar中是exe可执行文件,下面是校验码:
大小: 66070 字节
修改时间: 2011年8月10日, 15:19:51
MD5: 0CAB365E4A42F83FDABAA5AB011DC0A9
SHA1: 3F0972645F15BA6DB8F70A7EF3F9C760607B684B
CRC32: 8F22B704
转载请注明出处
分享到:
相关推荐
下的tail命令,可以在实时查看日志打印内容。下载到path环境变量下面。
Windows平台下类似Linux/Unix tail命令的小工具
windows下用tail指令,xp sp3测试通过
windows下使用tail命令-tail2win 下载之后解压到c:/windows/system32目录下 然后就可以像linux那样使用tail -f 指令
Linux有一个tail命令可以实时输出文本文件内容 而windows却没有类似的命令 这回用这个工具可以在windows里可以使用tail命令了...方法:解压缩,把tail.exe放到c:\windows\system32\目录下,就可以在命令行中使用tail命令了
将文件copy到windows/system32/下 在命令行即可和linux一样会使用tail命令
可实现在Windows操作系统下使用tail查看日志命令的工具,将其下载解压后,tail.exe放置C:\Windows\System32路径下,双击打开则可使用
windows实现tail 命令查看程序运行日志 使用方法:下载后解压,把tail.exe 复制到 目录:C:\Windows\System32 下 直接输命令就可以了
tail for Windows 是 Windows 下的 tail DOS 命令(类似 UNIX/Linux 下的相同命令)。可用来显示文件尾部内容以及跟踪/监控文件内容变化。你也可以借助重定向符号(> 或 >>)从一个文件的指定行号开始截取内容生成另...
windows下实现模拟linux的 tail -f 文件名 命令的实用工具,内含使用说明,工具很小,只有一个几十kb的exe执行文件。
复制到 c:\windows\system32\ 然后命令行执行 tail -f xxx.log即可。
window下也可享受跟linux下tail命令一样的方便与强大。
windows下类似linux的tail工具,可以实时跟踪日志文件,便于调试程序。
Tail 是一种基于命令行的文件实时监控和查看器,是对 UNIX 'tail -f' 命令的Windows移植。Tail 可以快速显示大文件的末尾部分,而无需加载整个文件。并且其可以用于查看一个正在增长的文件。Tail 仅是一个文件查看...
这个是开源的tail工具,有界面的,运行于windows环境。纯鼠标操作,还可以设置关键字过虑与高亮,在日志里面如果出现异常日志时,就可以通过这个功能只显示有问题的行。而不需要被其它正常日志信息阻碍视线
tail.exe -f 文本文件完整目录
Windows下的图形化Tail工具源代码,方便查看动态增长文件的易用工具; WIN32 API编写; 支持使用简单正则表达式的Filter功能; 支持快速键盘操作;
windows 环境下的模拟linux tail 命令的工具,简单好用。
linux有tail, 所以提供一份windows系统的tail.exe,放入C:\Windows\System32\ 下面即可以实现linux下的tail文件功能