说明:本文来自老男孩教育23期第三周课程李想同学的问题及老男孩的解答后学生的总结。
在整理diff命令的时候,突然奇想diff是比较两个文件不同。那我能不能通过diff把两个文件不同之处比较出来并打印并指明是来自那个文件?
下面是我创建两个文件file1和file2,其内容如下
[root@lx data]# cat file1 I am oldboy,myqq is 31333741 1234 fdsadas fdafdggfs kio323423 543rsgrsq [root@lx data]# cat file2 fdsadas 34fdafdggfs kio323423
下面是我写的一个简单的脚本
#!/bin/bash cd /root/data file1=(`diff -a file1 file2|grep'^<'|sed -r 's/^< (.*)/\1/g'`) file2=(`diff -a file1 file2|grep'^>'|sed -r 's/^> (.*)/\1/g'`) for m in ${file1[*]} do echo "the '$m' is from file1" done for n in ${file2[*]} do echo "the '$n' is from file2" done
其打印结果如下
[root@lx data]# sh /shell/2.sh the 'I' is from file1 the 'am' is from file1 the 'oldboy,myqq' is from file1 the 'is' is from file1 the '31333741' is from file1 the '1234' is from file1 the 'fdafdggfs' is from file1 the '543rsgrsq' is from file1 the '34fdafdggfs' is from file2
此脚本的有一个bug,我想要的是I am oldboy,myqq is 31333741作为一个整体来输出,而不是分个输出
student:于是请教老师怎样解决这个问题?
oldboy:老男孩老师给出了 IFS=$'\n'这个参数
#!/bin/bash cd /root/data IFS=$'\n' #IFS='\n' file1=(`diff -a file1 file2|grep '^<'|sed -r 's/^<(.*)/\1/g'`) file2=(`diff -a file1 file2|grep '^>'|sed -r 's/^>(.*)/\1/g'`) for m in ${file1[*]} do echo"the '$m' is from file1" done for n in ${file2[@]} do echo"the '$n' is from file2" done
打印输出结果为:
[root@lx data]# sh /shell/2.sh the 'I am oldboy,myqq is 31333741' is from file1 the '1234' is from file1 the 'fdafdggfs' is from file1 the '543rsgrsq' is from file1 the '34fdafdggfs' is from file2 [root@lx data]# sh /shell/2.sh the 'I am oldboy,myqq is 31333741 1234 fdafdggfs 543rsgrsq' is from file1 the '34fdafdggfs' is from file2
总结:
查看了下IFS,了解到IFS是内部域分隔符;此题IFS=$'\n'默认以换行作为分隔符; IFS='\n',是以n字符作为分隔
1. IFS的默认值为:空白(包括:空格,tab, 和新行),将其ASSII码用十六进制打印出来就是:20 09 0a (见下面的shell脚本)。
2. IFS对空格的空白的处理和其他字符不一样,左右两半的纯空白会被忽略,多个连续的空白被当成一个IFS处理。
3. S*中使用IFS中的第一个字符。
4. awk中的FS(域分隔符)也和IFS有类似的用法和作用
老男孩老师点评:此问题略微有些偏门,不过了解下也是有好处的。