php 仿 linux cat 命令实现代码

<?php
/**
 * Usage:
 * cat.php -n 10 -f test.log --line-numbers -r -h --help
 */
$longopts 	= array('line-numbers', 'help'); //显示行号
$opts 	= getopt('n:f:rh', $longopts); // n: 读取的行数, f: 读取的文件名
$lines 	= isset($opts['n']) ? intval($opts['n']) : 10; //默认读取 10 行内容
$fname 	= isset($opts['f']) ? $opts['f'] : ''; //处理的文件名
$show_line_numbers = isset($opts['line-numbers']) ? true : false; //默认不需要显示编号
$reverse 	= isset($opts['r']) ? true : false; //倒序显示文件内容
$show_help 	= ( isset($opts['h']) || isset($opts['help']) ) ? true : false; //显示帮助信息

if(PHP_SAPI != 'cli') {
	exit('Please run under the command line!');
}

if($show_help) {
	show_help_info();
	exit();
}

/**
 * 显示帮助信息
 */
function show_help_info() {
	$str = <<<'DATA'
Usage: php cat.php -[n|f|r|h] --[line-numbers|help]
Options:
-n 读取的行数, 默认显示 10 行
-f 读取的文件名
-r 是否倒序显示文件内容, 默认为正序
--line-numbers 是否显示行编号, 默认不显示
--help,-h 显示帮助信息
DATA;
	echo ch_str_to_gbk($str);
}

/**
 * 根据系统类型转换字符串编码
 */
function ch_str_to_gbk($str) {
	// 系统类型判断
	if(stripos(PHP_OS, 'WINNT') !== false) {
		// win
		$str = iconv('UTF-8', 'GBK', $str);
	}
	return $str;
}

/**
 * @param $fh 文件句柄
 * @param $lines 读取的行数
 * @param $show_line_numbers 是否显示编号
 */
function get_lines($fh, $lines, $show_line_numbers) {
	$data = array();
	$start = 0;
	while(!feof($fh) && $start < $lines) {
		$ln = $show_line_numbers ? ($start+1) . ' ' : ''; //追加编号
		$data[] = $ln . fgets($fh);
		$start++;
	}
	return implode($data);
}

/**
 * 倒序显示文件内容
 * @param $fh 文件句柄
 * @param $lines 读取的行数
 * @param $show_line_numbers 是否显示编号
 */
function get_lines_reverse($fh, $lines, $show_line_numbers) {
	$data = [];
	$pos = -1;
	$eof = false; //标记是否读完所有内容
	while ($lines > 0) {
		$line = '';
		$c = '';
		while($c != "\n") {
			if(fseek($fh, $pos, SEEK_END) == 0) {
				$line = $c . $line;
				$c = fgetc($fh);
				$pos--;
			}
			else {
				$line = $c . $line; //拼接最后一个字符
				$eof = true;
				break;
			}
		}
		$line .= "\n"; //添加换行符
		array_unshift($data, $line);
		$lines--;
		if($eof) { //结束,退出循环
			break;
		}
	}
	if($show_line_numbers) { //追加编号
		$index = 1;
		foreach ($data as $k=>$d) {
			$data[$k] = $index . ' ' . $d;
			$index++;
		}
	}
	return implode($data);
}

if(!file_exists($fname)) {
	exit(sprintf('file [%s] not found!', $fname));
}

$fh = fopen($fname, 'r');
if(!$fh) {
	exit(sprintf('open file [%s] error!', $fname));
}

if($reverse) {
	$str = get_lines_reverse($fh, $lines, $show_line_numbers);
}
else {	
	$str = get_lines($fh, $lines, $show_line_numbers);
}
$str = ch_str_to_gbk($str);
echo $str;

fclose($fh); //close

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值