遇到看起来不会的问题,学会把问题拆解为自己能解决的一个个小问题

                                               ---记用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部分,改动了老男孩老师原来的脚本,我这里用了字符多次匹配的正则表达式法,就是对于行尾的多个+号,直接替换为空。

 老男孩的原始脚本参见:

上面这个问题,对于高手来说,并不难,方法也更多,对于初学者,怎么去处理一个看起来不知道怎么处理的问题,要学会把问题分解成一个个自己能解决的小问题,各个击破,从而解决整个问题。