Chinaunix

标题: sed实现在指定行之前读入文件内容 [打印本页]

作者: songyc_2015    时间: 2015-06-08 22:18
标题: sed实现在指定行之前读入文件内容
各位大神,好!
请教一个问题:
在指定行之前读入文件内容,如:
  1. $cat a.txt
  2. aaa
  3. bbb
复制代码
  1. $cat b.txt
  2. 1
  3. 2
  4. 3
复制代码
在b.txt的第2行之前读入a.txt的内容,想得到结果:
  1. 1
  2. aaa
  3. bbb
  4. 2
  5. 3
复制代码
  1. $sed '2{r a.txt
  2. }' b.txt
  3. 1
  4. 2
  5. aaa
  6. bbb
  7. 3
  8. 读入a.txt的内容在第2行之后了,结果不正确
复制代码
  1. sed '2{r a.txt
  2. N;}' b.txt
  3. 1
  4. aaa
  5. bbb
  6. 2
  7. 3
  8. 得到的结果正确
复制代码
问题1:比较上面的命令,发现第二条命令比第一条了N命令,则可以得到正确的结果,请问为什么?是什么原理?
问题2:如果想在最后一行之前读入a.txt的内容,sed怎么实现?结果如:
  1. 1
  2. 2
  3. aaa
  4. bbb
  5. 3
复制代码
望各位大神不吝赐教~~~~~
作者: lifayi2008    时间: 2015-06-09 10:07
本帖最后由 lifayi2008 于 2015-06-09 10:08 编辑

看错了
作者: blackold    时间: 2015-06-09 10:11
回复 1# songyc_2015


    建议你在"某行之后"读入……
作者: lifayi2008    时间: 2015-06-09 10:16
你也没看问题二 回复 3# blackold


   
作者: blackold    时间: 2015-06-09 10:21
回复 4# lifayi2008


    我认真看完了。
作者: songyc_2015    时间: 2015-06-09 10:24
回复 3# blackold
黑哥好!可否帮忙解答下第一个疑问?
sed在执行到2{...}时,此时模式空间的内容为"2",r a.txt读入文件的内容不是读入到模式空间的(之前看过的一个贴子,现在忘了是哪个帖子),那么读入的a.txt内容是保存到哪里的?sed又是怎么触发打印a.txt内容的?

建议你在"某行之后"读入……

如果已知条件就是"最后一行之前读入a.txt的内容",按照您的建议就是在倒数第2行读入a.txt的内容,那么定位倒数第2行呢?
作者: songyc_2015    时间: 2015-06-09 10:25
回复 2# lifayi2008
可能是描述不够准确吧
作者: blackold    时间: 2015-06-09 10:45
回复 6# songyc_2015


    r 的内容并没有放入模式空间。而且,它在何时输出,这不好控制。

    可以先把文件读入到变量,再用s命令进行替换,这比较好控制。
作者: blackold    时间: 2015-06-09 10:49
或者用 ed , 对这种问题,ed 容易实现。
作者: songyc_2015    时间: 2015-06-09 11:06
回复 8# blackold

感谢黑哥的建议,ed不太懂
作者: blackold    时间: 2015-06-09 11:18
本帖最后由 blackold 于 2015-06-09 11:22 编辑

回复 10# songyc_2015

ed
  1. ed - b.txt <<EOF
  2. $-1r a.txt
  3. w
  4. EOF
复制代码
sed:
a="$(<a.txt)"
a="${a//$'\n'/\\n}"
sed '$s/^/'"$a"'\n/;' b.txt

作者: songyc_2015    时间: 2015-06-09 11:37
本帖最后由 songyc_2015 于 2015-06-09 11:46 编辑

回复 11# blackold
ed那么简单就实现了?黑哥大牛啊,去研究研究ed,谢谢
这种情况sed确实不好处理,如果a.txt文件太大的话,还很容易出问题·~~~~
作者: jason680    时间: 2015-06-09 12:41
回复 12# songyc_2015

筷子喝汤?
大家认为是牛,还是错用工具?

$ cat a.txt
a1
a2
a3

$ cat b.txt
b1
b2
b3
b4

$ awk 'NR==2{while(getline a < "a.txt")print a}1' b.txt
b1
a1
a2
a3
b2
b3
b4


   
作者: songyc_2015    时间: 2015-06-09 13:09
本帖最后由 songyc_2015 于 2015-06-09 13:10 编辑

回复 13# jason680
谢谢Jason大神回复,并不是只允许用筷子喝汤,只是不熟悉sed,大家讨论下而已
作者: jeffreyst    时间: 2015-06-09 21:10
楼主这个题很有意思,看下这个sedsed的执行流程,或许对你有帮助,

QQ图片20150609210942.png (24.86 KB, 下载次数: 123)

QQ图片20150609210942.png

作者: songyc_2015    时间: 2015-06-09 22:13
回复 15# jeffreyst
谢谢jeff兄
作者: 聆雨淋夜    时间: 2015-06-10 14:04
  1. sed '${h;s/.*/cat a.txt/e;G}' b.txt
  2. 1
  3. 2
  4. aaa
  5. bbb
  6. 3
复制代码

作者: songyc_2015    时间: 2015-06-10 22:17
本帖最后由 songyc_2015 于 2015-06-10 22:21 编辑

回复 17# 聆雨淋夜
厉害,学习了,昨晚我也想到一个,和你类似,你的方法更简洁点只不过这个方法是调用了另一个进程了
  1. sed '${x;s#.*#sed -n 'p' a.txt#e;p;x}' b.txt
  2. 1
  3. 2
  4. aaa
  5. bbb
  6. 3
复制代码

作者: 我爱你我的菜    时间: 2015-09-07 10:28
awk 'FNR==NR{a[$1]=$1;}NR!=FNR{print $0;if(FNR==1){for(i in a) print a[i]}}' test.txt t1.txt
作者: sunzhiguolu    时间: 2015-09-07 10:54
回复 1# songyc_2015
各位大神好,菜鸟觉得 r 命令读取到的内容并没有读入到模式空间.
sed -nr '
2 {
r a.txt
}' b.txt

查看输出结果,b.txt的文本内容依然被打印出来
至于 N 命令,如果上面的条件成立; 那么 N 命令就好解释了,为了确保模式空间与输入行之间的完整性与一致性强迫将 a.txt 内容提前打印出来!

如有不对之处,还请大家给予指点. 这也是我的粗浅理解.

   




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2