学习命令的重要方法就是综合运用,达成一定功能。
关于文件倒序输出或显示,本人写了篇短文《Linux centos7 for循环与文件倒序》,主要讨论用for如何实现文件倒序输出,欢迎指正。
本文从综合运用命令入手,讨论文件倒序。
一、常用命令及组合
文件查看的基本命令cat是初学linux centos就要掌握的,应用广泛,功能强大。
通过-n选项,可以在显示每行内容时,在左侧显示行号。
通过-A选项,可以在显示每行内容时,显示不可打印字符。
在cat命令中添加多个文件,可以同时显示文件内容,且按文件顺序依次排列。
cat命令把文件内容送到屏幕进行标准输出,也可以通过管道符|转到下一条命令处理;也可以重定向到另一个文件。
但是,当文件较大,以M或G计时,使用此命令应慎重。文件行数太多,也建议缓用,用其他命令可以更合适!
不常用,但直接倒序显示的命令是tac。
如果不知道tac命令,还想倒序查看文件内容,首先想到的就是把文件行的顺序翻转一下就可以了。
用命令实现:
cat -n 文件名 #先正序查看文件,同时添加选项-n,显示行号
cat -n 文件名 | sort -nr
sort的-n选项表示按数字排序,-r表示反序。
如果查看文件内容后想保存为另一文件,可以重定向;不想保留左边的行号,可以利用剪切命令cut,只保存右边内容
cat -n 文件名 | sort -nr|cut -f2 >新文件名
如cat -n 具有同样功能的命令是nl,可自行测试。
二、循环处理
应用循环处理文件,是明智的选择。
想用循环读取文件,需对for循环与while循环进行了解。
1.for
for处理文件倒序,可参考文章《Linux centos7 for循环与文件倒序》。
此处仅就关键之处再讨论一下。
for循环读取文件时,遇到空格或制表符,会当作一个单元结束(for循环读取文件时就结束一次读取),而不象while循环只有遇到\n换行符才算结束一个单元(一行)。
这就引入了shell内置变量IFS的概念。
通过修改系统的IFS(内部域分隔符),自定义IFS,定义为\n,来实现的。
for循环的IFS默认是空格或制表符,for循环按行读取时应重新设置IFS=$'\n'。
为避免其他命令或程序出现错误,for循环执行完毕应更改回默认IFS设置。
应用数组的概念,实现for循环很方便:
oldifs=$IFS;IFS=$'\n';j=0;for line in $(cat 文件名);do file[$j]=$line;let j++;done; for((j=j-1;j>=0;j--));do echo ${file[$j]};done;IFS=$oldifs
其中的数组名可以自定义。
2.while
应用while循环,实现倒序输出很容易:
i=0
#将读取的行内容保存到数组中
while read line;do arr[$i]=$line;((i++));done <filename
#倒序输出
for((i=i-1;i>=0;i--));do echo ${arr[$i]};done
与for循环相比,while默认IFS是\n,就不需要重新设置了。
三、特殊方法
为参考起见,把其他方法的主要命令列出如下,可讨论比较。
1.sed方法
sed '1!G;h;$!d' filename
其中的’1!G;h;$!d’可以这样理解:
1!G — 只有第一行不执行G命令,将保持空间中的内容追加到模式空间
h —每一行都执行h命令,将模式空间中的内容拷贝到保持空间中
$!d —除了最后一行不执行d命令,其它行都执行d命令,删除当前行。
这个操作很经典,重点是理解保持空间与模式空间的数据交换、传递与保存。
同样达到目的的命令:
sed '2,$G;h;$!d' filename #这是前面代码的另一种写法:第1行不执行G,就是2,$(最后一行)执行G命令。
sed -n '1h;1!G;$!x;$p' filename
sed -n '1!G;h;$p' filename
上面两行代码是采用安静方式打印时的写法。
2.AWK方法
awk '{line[NR]=$0}END{for(i=NR;i>0;i--)print line[i]}' filename
代码思路:先将内容存入数组,END后NR为最后一行行号,利用for循环反序输出内容
此方法利用数组功能,与while循环同样思路。
3.vim方法
在底行命令模式下执行 :g/^/m0
g 全局操作
m 移动
m0 移动到文件顶部(m后是数字0)
命令功能:每行都移动到顶部一次。结果就是正序变反序。
命令执行前
回车确认后
每行的第1个字符都高亮显示,表明这个命令对所有行都进行了操作。