遇到看起来不会的问题,学会把问题拆解为自己能解决的一个个小问题
---记用paste和tr合并多行文本的思路
一个题目是这样的,有一个文件,内容如下:
1 2 3 4 5 6 7 8 9 10 |
最后一行是空行,要求把这些行用+连接成一行,并求和,即组成这样的形式:
1+2+3+4+5+6+7+8+9+10=55
看上去,不知道怎么做。
那么把问题分解一下
(1):把多行文本连成一行
(2):这些文本之间用+连接
(3):连接之后的文本的末尾用加上一个=号
(4):对以上表达式求和
沿着这个思路:
问题(1),(2)可以用paste解决
paste命令可以用来合并文件,我们也可以用它来合并文本。
看看paste 的-s参数
paste one file at a time instead of in parallel -s, --serial |
意思就是:
一次粘贴一个文件,而不是并行粘贴(即分成好几块来粘贴)
用这个参数就可以把一个文件的多行合并成一行。
-s, --serial paste one file at a time instead of in parallel -d, --delimiters=LIST reuse characters from LIST instead of TABs |
再看-d参数:重复使用(-d参数)面的字符来取代tab,paste命令合并的各个项目之间默认是用tab键分割的,为了使用上面的 表达式形式,用-d "+" 的形式指定用+分割各个字符串。
问题(4),求和,可以用linux的bc命令。
好,至此,我们解决了问题(1)(2)(4),先看一下效果。
[root@cohoa ~]# sed '/^$/d' ett.txt | paste -d "+" -s | bc 55 |
好了,这样就解决了问题(1)(2)(4),那么问题(3)呢?
我们是想要打印一个=号到表达式的行尾,那么,用echo命令可以实现。
并用变量记住上面已经连接好的表达式,把=打印在表达式的行尾。
好,至此,所有问题,我们都能解决了。
写成脚本,内容如下:
[root@cohoa ~]# vi add_bc.sh |
#!/bin/bash pluschar="`sed '/^$/d' ett.txt | paste -d "+" -s`" echo -en "${pluschar}=`echo ${pluschar}|bc`\n" |
其中,sed的作用是去掉空行,不然会有麻烦,呵呵,试试就知道了。
老男孩老师的博客,用tr解决这个合并的问题的,之前,不会用tr命令,看了老男孩老师的博客,学会了用tr命令来解决的方法,也从思路分析一下。
思路:每行都是有换行符的,要是把这些换行符全部替换成+号,这些字符串就构成了上面要求的表达式了,注意空行,要是开始没有用sed去掉空行,是要对这个进行处理的,去掉行尾多余的+号。
下面引用老男孩老师的脚本
#!/bin/bash pluschar=` cat ett.txt |tr "\n" "+"| sed 's@+\{2\}@@'` echo -en "${pluschar}=`echo ${pluschar}|bc`\n" |
注:对老男孩老师的脚本,我略有改动,主要是为了练习一下sed。
对于老男孩老师的原来脚本改动的,特意标注一下,以尊重老男孩老师的版权:
第二行,最后的sed部分,改动了老男孩老师原来的脚本,我这里用了字符多次匹配的正则表达式法,就是对于行尾的多个+号,直接替换为空。
老男孩的原始脚本参见:
上面这个问题,对于高手来说,并不难,方法也更多,对于初学者,怎么去处理一个看起来不知道怎么处理的问题,要学会把问题分解成一个个自己能解决的小问题,各个击破,从而解决整个问题。