《Linux命令、编辑器与Shell编程》读书笔记4.3-其他数据文件处理命令(tr,sort,cut,paste,join,uniq,split)

一、转换和删除重复命令——tr

【命令格式】

tr [option] [string1] [string2]



【举例】

1. 字符替换:

> echo "this is a test string."|tr -s "[a-z]" "[A-Z]"

THIS IS A TEST STRING.

#使用重定向、可以实现文本内容的大小写转换

> tr -s "[a-z]" "[A-Z]" < list.txt

#将指定的字母转换成对应的形式

> echo "this is a test string." | tr -s "[test]" "[TEST]"
ThiS iS a TEST STring.

*这里要注意,如果对同一个字母定义两个不同的转换后字符,则以最后一个为准,比如:

> echo "this is a test string." | tr -s "[test]" "[TESf]"
fhiS iS a fESf Sfring.

#替换文本中的特殊符号,比如将##替换为制表符\t

假设存在以下文件:

> cat student2
283214321##Liulu$$0::A**B&&0\\
282351512##Yangrui$$B::C**0&&0\\
283245314##Xuli$$0::0**B&&D\\
293831944##Xiayu$$0::0**0&&0\\
213432143##Heli$$A::0**A&&B\\
279058640##Liyan$$B::B**C&&0\\
> tr -s "##" "\t" < student2
283214321       Liulu$$0::A**B&&0\\
282351512       Yangrui$$B::C**0&&0\\
283245314       Xuli$$0::0**B&&D\\
293831944       Xiayu$$0::0**0&&0\\
213432143       Heli$$A::0**A&&B\\
279058640       Liyan$$B::B**C&&0\\

2. 删除字符:

#删除重复的字符:

> echo "HHHHHHHHeeeeellooooooo" | tr -s "Heo"
Hello

#也可以引用一个字符集去删除重复字符

> echo "HHHHHHHHeeeeellooooooo" | tr -s "[a-z][A-Z]"
Helo

#删除多余的空行:

> cat duplicate.txt
    234   2134


 321   43221


          4321  39875



3212    8549

> tr -s "\n" < duplicate.txt
    234   2134
 321   43221
          4321  39875
3212    8549

或者:

> tr -s "\012" < duplicate.txt
    234   2134
 321   43221
          4321  39875
3212    8549

#删除指定的特殊字符

> echo "my name is suse."| tr -d "msu"
y nae i e.

二、排序命令——sort

sort可以按一个或多个字段排序,还可以合并文件,虽然速度可能不快,但用途较广。

【命令格式】

sort [option] [filename]

【常用选项】


【举例】

指定某一列为排序的主键:


#假设存在上述文件,按照第二列排序:

> sort -k2 list.txt

#以第一列中的第二个字符排序:

> sort -k1.2 list.txt

#也可以在上面的基础上加入n选项,进一步按照数字大小进行排序

> sort -k1.2n list.txt

#指定多个字段进行排序,下面的例子含义是,先按第一列(第二个字符)排序,之后在这个范围内再按第四列排序:

> sort -k1.2,4n list.txt

#也可以写成

> sort -k1.2 -k4n list.txt

#使用cu检查文件是否排序或存在重复行

#使用uf删除重复行并忽略大小写后进行排序

#使用m选项合并文件并排序、之后输出到一个新文件中,被合并的文件列数应该相同

sort -m student2.1 student2.2 > student_sort

*如果是两个很大的文本文件进行合并排序,应该先对每个文件进行排序、再合并,这样可以提升合并的速度

#与其他命令配合使用,比如要查看/etc下最大的五个文件:

> ls -l /etc | awk '{print $1,$5,$9}' | sort -n -k2 | tail -5


三、数据剪切命令——cut

【命令格式】

cut [option] [filename]


*Linux中的cut命令不会改变原有文件的内容,这一点和windows的“剪切”有区别。

#复制list_name.txt文件中每列的前四个字节:

> cut -b-4 list_new.txt

#复制list_name.txt文件中每列第5到第8个字符:

> cut -c5-10 list_new.txt

#复制list_name.txt文件中第1,2,3,5列:

> cut -f1-3,5 list_new.txt


四、数据粘贴命令——paste

paste命令一般和cut配合使用,命令格式如下:

paste [option] [file1,file2...]

【常用选项】

d:对新生成的文本指定新的字段分隔符,默认为Tab

s:将粘贴的内容合并成行,即横向粘贴,默认为纵向

假设存在以下文件:

> cat cut.txt
1234
2234
3234
4234
5234
> cat cut1.txt
aa1
bb2
cc3
aa2
bb3
cc4

#将cut1.txt粘贴到cut.txt后面

> paste cut.txt cut1.txt
1234  aa1
2234  bb2
3234  cc3
4234  aa2
5234  bb3

#将cut.txt粘贴到cut1.txt后面

> paste cut1.txt cut.txt
aa1 1234
bb2 2234
cc3 3234
aa2 4234
bb3 5234

#横向粘贴

> paste -s cut1.txt cut.txt
aa1  bb2 cc3    aa2     bb3    cc4
1234 2234   3234        4234   5234
#指定第一二列用tab分割,第二三列用#分割

> paste -d'\t#' cut.txt cut.txt cut.txt
1234 1234#1234
2234 2234#2234
3234 3234#3234
4234 4234#4234
5234 5234#5234

#假设存在文件serialNum,用-表示来自管道的文件,如果想把serialNum放到后面,只需把它与-交换位置即可:

> cat serialNum
1
2
3
4
5
> cat cut.txt | paste -d"#" serialNum -
1#1234
2#2234
3#3234
4#4234
5#5234

*不同的Shell可能会把同一行按照不同的分隔符分割(比如tab后面有空格,则被当做两列),注意反复调试


五、数据连接命令——join

这个命令与数据库里的join意义类似,将两个具有相同列的文件,通过这个相同列进行关联后输出结果

【命令格式】

join [option] file1 file2

【常用选项】


上面这句话需要解释一下:join允许在参数后面加数字1、表示文件1的参数,加数字2表示文件2的参数

假设存在以下两个文件:

> cat join1.txt
1       1234    33      56      23
2       2234    46      43      98
3       3234    97      34      56
4       4234    85      33      57
5       5234    43      98      87
6       6234    87      45      13
7
> cat join2.txt
1       aa1     1234
2       bb2     2234
3       cc3     3234
4       aa2     4234
5       bb3     5234

        aa3     6234

#直接将join1.txt和join2.txt关联:

> join join1.txt join2.txt
1 1234 33 56 23 aa1 1234
2 2234 46 43 98 bb2 2234
3 3234 97 34 56 cc3 3234
4 4234 85 33 57 aa2 4234
5 5234 43 98 87 bb3 5234
可以看出,这样只能输出有关联的行。

#使用参数a1,a2输出两个文件中的无关联行:

> join -a1 -a2 join1.txt join2.txt
1 1234 33 56 23 aa1 1234
2 2234 46 43 98 bb2 2234
3 3234 97 34 56 cc3 3234
4 4234 85 33 57 aa2 4234
5 5234 43 98 87 bb3 5234

6 6234 87 45 13
7
aa3 6234
#使用v1,v2只显示没有关联的行:

> join -v1 -v2 join1.txt join2.txt

6 6234 87 45 13
7
aa3 6234
#使用o选项,只输出join1.txt中的2,3,4,5列和join2.txt中的第2列,之后使用awk命令输出规范化文本、并统计join1.txt中的3,4,5列的总和与平均值

> join -o "2.2,1.2,1.3,1.4,1.5" join1.txt join2.txt|awk '{printf "%-15s %-10s %d %d %d %d %d\n",$1,$2,$3,$4,$5,($3+$4+$5),($3+$4+$5)/3}'
aa1             1234       33 56 23 112 37
bb2             2234       46 43 98 187 62
cc3             3234       97 34 56 187 62
aa2             4234       85 33 57 175 58
bb3             5234       43 98 87 228 76

#如果关联列不在第一行,就需要使用选项“j”指定要关联的列,比如上面两个文件要通过第二、三列进行关联,然后输出第7,1,3,4,5列和3,4,5列的和与平均值

> join -j1 2 -j2 3 join1.txt join2.txt | awk '{printf "%-15s %-10s %d %d %d %d %d\n",$7,$1,$3,$4,$5,($3+$4+$5),($3+$4+$5)/3}'
join: file 1 is not in sorted order
aa1             1234       33 56 23 112 37
bb2             2234       46 43 98 187 62
cc3             3234       97 34 56 187 62
aa2             4234       85 33 57 175 58
bb3             5234       43 98 87 228 76

*如果两个要连接的文件主键没有排序,则在执行join命令时就会报错:join: file 1 is not in sorted order;因此,保险起见,在执行join之前最好把文件按照要关联的列排序一下

#使用选用t指定特定的分隔符分割文件并连接

> cat join1#.txt
1#1234#33#56#23
2#2234#46#43#98
3#3234#97#34#56
4#4234#85#33#57
5#5234#43#98#87
6#6234#87#45#13
7
> cat join2#.txt
1#aa1#1234
2#bb2#2234
3#cc3#3234
4#aa2#4234
5#bb3#5234

#aa3#6234
> join -t"#" join1#.txt join2#.txt
1#1234#33#56#23#aa1#1234
2#2234#46#43#98#bb2#2234
3#3234#97#34#56#cc3#3234
4#4234#85#33#57#aa2#4234
5#5234#43#98#87#bb3#5234

#假如两个文件中某些行的关联列值不同或为空,可以使用-e选项填充这些行使其保留下来进一步进行补齐操作,比如要将join1.txt和join2.txt文件的所有行都关联显示出来,对应不上的列使用#号填充:

> join -e "#" -a1 -a2 -o "1.1,1.2,1.3,1.4,1.5,2.1,2.2,2.3" join1.txt join2.txt
1 1234 33 56 23 1 aa1 1234
2 2234 46 43 98 2 bb2 2234
3 3234 97 34 56 3 cc3 3234
4 4234 85 33 57 4 aa2 4234
5 5234 43 98 87 5 bb3 5234
# # # # # # # #
6 6234 87 45 13 # # #
7 # # # # # # #
# # # # # aa3 6234 #

*注意:使用e选项进行填充时,必须搭配o和a选项使用,否则join命令找不到要填充的位置。


、去重复命令——uniq

【命令格式】

uniq [option] [input[output]]


【举例】

#假设存在如下文件

> cat uniq1.log
asdf1   aaAA
asdf2   aaAA
asdf3   aabb
asdf3   aabb
asdf5   AABB
asdf4   BBcc
asdf6   BBcc
asdf6   bbCC
asdf6   bbCC
asdf6   BBCC
asdf6   BBcc
asdf6   BBcc

#使用c和d输出重复的行并统计重复次数:

> sort uniq1.log | uniq -cd
      2 asdf3   aabb
      2 asdf6   bbCC
      3 asdf6   BBcc

*之所以要先排序,是因为uniq只会统计连续重复的行,否则就会出现如下统计结果:

> uniq -cd uniq1.log
      2 asdf3   aabb
      2 asdf6   bbCC
      2 asdf6   BBcc

#使用f选项忽略第一个字段,然后使用s3从第2个字段的第三个字符开始对比:

> sort -k2 uniq1.log | uniq -f1 -s3

asdf1   aaAA
asdf3   aabb
asdf5   AABB
asdf6   bbCC
asdf4   BBcc
asdf6   BBCC


七、分割文件命令——split

顾名思义,将大文本文件按照一定规则分割为若干个小文件。

【文件格式】

split [option] [input file] [output file]

【常用选项】

l:按行对文件进行分割

b:按字节对文件进行分割

C:按字节对文件进行分割,split会尽量保持一个整行

d:使用数字作为输出文件的后缀

在指定输出文件名称后,split会将输出文件以指定名称为前缀、在其后加上诸如aa,ab之类的后缀作为分割后的文件名

【举例】

假设存在如下文件,共25行:

> cat list.txt
1234    aa1     23      32      65
2234    bb2     23      34      66
3234    cc3     24      36      67
4234    aa2     25      38      68
5234    bb3     26      40      69
6234    cc4     27      42      70
7234    aa3     28      44      71
8234    bb4     29      46      72
9234    cc5     30      48      73
1567    aa4     31      50      74
2567    bb5     32      52      75
3567    cc6     33      54      76
4567    aa5     34      56      77
5567    bb6     35      58      78
6567    cc7     36      60      79
7567    aa6     37      62      80
8567    bb7     38      64      81
9567    cc8     39      66      82
1790    aa7     40      68      83
2790    bb8     41      70      84
3790    cc9     42      72      85
4790    aa8     43      74      86
5790    bb9     44      76      87
6790    cc1     45      78      88
7790    aa9     46      80      89

#将其按照每7行分割一次的办法进行分割:

> split -l 7 list.txt list
> ls
total 20
-rw-r--r-- 1 xingkai users 126 Nov 28 11:00 listaa
-rw-r--r-- 1 xingkai users 126 Nov 28 11:00 listab
-rw-r--r-- 1 xingkai users 126 Nov 28 11:00 listac
-rw-r--r-- 1 xingkai users  72 Nov 28 11:00 listad
-rw-r--r-- 1 xingkai users 450 Nov 28 10:52 list.txt
linux-gwl8 a1/split> wc -l lista*
  7 listaa
  7 listab
  7 listac
  4 listad
 25 total

#按文件大小(字节)分割,将上述文件分割为若干个100B的小文件:

> split -b 100 list.txt list
> ls
total 24
-rw-r--r-- 1 xingkai users 100 Nov 28 11:01 listaa
-rw-r--r-- 1 xingkai users 100 Nov 28 11:01 listab
-rw-r--r-- 1 xingkai users 100 Nov 28 11:01 listac
-rw-r--r-- 1 xingkai users 100 Nov 28 11:01 listad
-rw-r--r-- 1 xingkai users  50 Nov 28 11:01 listae
-rw-r--r-- 1 xingkai users 450 Nov 28 10:52 list.txt
> wc -l lista
> wc -l lista*
  5 listaa
  6 listab
  5 listac
  6 listad
  3 listae
 25 total



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值