bash SED:将文件中的行复制到另一个文件中的特定行
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/32223572/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
SED: copy lines from a file to specific line in another file
提问by mYself
I can do this using the following example. The 1st command will output the lines 16...80 from file1
to patch
, while the 2nd will insert the contents of patch
after line 18 to file2
:
我可以使用以下示例执行此操作。第一个命令将输出第 16...80 行 from file1
to patch
,而第二个命令将插入第patch
18 行之后的内容to file2
:
sed -n 16,80p file1>patch
sed -i 18rpatch file2
However, I would like to copy directly from one file to another without using a temporary file in-between, in one command using sed (not awk, etc.). I'm pretty sure this is possible, just don't know how.
但是,我想直接从一个文件复制到另一个文件,而不使用中间的临时文件,在一个使用 sed(而不是 awk 等)的命令中。我很确定这是可能的,只是不知道如何。
回答by Wintermute
Doing this with sed requires some additional shell trickery. Assuming bash, you could use
使用 sed 执行此操作需要一些额外的 shell 技巧。假设 bash,你可以使用
sed -i 18r<(sed '16,80!d' file1) file2
Where <(sed '16,80!d' file1)
is substituted with the name of a pipe from which the output of sed '16,80!d' file1
can be read.
Where<(sed '16,80!d' file1)
替换为sed '16,80!d' file1
可以从中读取的输出的管道的名称。
Generally, I feel that it is nicer to do this with awk (if a little longer), because awk is better equipped to handle multiple input files. For example:
一般来说,我觉得用 awk 做这个更好(如果再长一点),因为 awk 更适合处理多个输入文件。例如:
awk 'NR == FNR { if(FNR >= 16 && FNR <= 80) { patch = patch NR == FNR { # While processing the first file
if(FNR >= 16 && FNR <= 80) { # remember the patch lines
patch = patch cp file2 file2~
awk ... file1 file2~ > file2
ORS
}
next # and do nothing else
}
FNR == 18 { # after that, while processing the first file:
head -80 file | tail -16 > patch
= patch sed -i '1,15 d
34 r patch
81,$ d' YourFile
# oneliner version
sed -i -e '1,15 d' -e '34 r patch' -e '81,$ d' YourFile
# prepend the patch to line 18
}
1 # and print regardless of whether the current
# line was patched.
ORS }; next } FNR == 18 { ##代码## = patch ##代码## } 1' file1 file2
This works as follows:
其工作原理如下:
##代码##However, this approach does not lend itself to in-place editing of files. This is not usually a problem; I'd simply use
但是,这种方法不适用于文件的就地编辑。这通常不是问题;我只是用
##代码##with the added advantage of having a backup in case things go pear-shaped, but in the end it's up to you.
具有备份的额外优势,以防万一事情变成梨形,但最终取决于您。
回答by Arif Burhan
I have done something similar using:
我使用以下方法做了类似的事情:
##代码##Check the documentation for your local versions of headand tail, and change the two integers to suit your requirements.
检查您本地版本的head和tail的文档,并更改这两个整数以满足您的要求。
回答by Farshad Falaki
i had this problem, i did it in 2 steps(1-tail 2-head), for example in a text file with 20 lines(test.txt), we want to copy lines from 13 to 17 to another file(final.txt),
tail -8 test.txt > temp.txt
head -5 temp.txt > final.txt
我遇到了这个问题,我分两步完成(1-tail 2-head),例如在一个有 20 行的文本文件(test.txt)中,我们想将 13 到 17 行复制到另一个文件(final.txt)。 txt),
tail -8 test.txt > temp.txt
head -5 temp.txt > final.txt
回答by NeronLeVelu
- order of line is not important.
- You can adapt a bit or batch it with variable like this
- 行的顺序并不重要。
- 您可以使用这样的变量对其进行调整或批量处理
sed -i "1,16 d
$(( 16 + 18 )) r patch
81,$ d" YourFile
sed -i "1,16 d
$(( 16 + 18 )) r patch
81,$ d" YourFile
but add some security about line count in this case.
但在这种情况下增加一些关于行数的安全性。
- if the
r
line is more than 1 line, following line are still counted from original place and final file is bigger than 80 - 16 lines
- 如果该
r
行超过 1 行,则以下行仍从原始位置开始计算,最终文件大于 80 - 16 行
i dont exactly test for line taken,excluded or modified (like 34 is the 18th line of cropped file),but principe is the same
我不完全测试所取、排除或修改的行(如 34 是裁剪文件的第 18 行),但原理是相同的
Explaination for Lines index references used in this sample:
本示例中使用的 Lines 索引引用的说明:
1,15
are the heading line to remove, so file take care lines from 16 in this case34
is the line to change the content and is the result of 18th line AFTER the first new content (line 16 in our case) so 16 + 18 = 3481,$
are trailing lines to remove,$
mean last line and 81 is the first line (after 80 that is taken) of the unwanted trailing lines.
1,15
是要删除的标题行,因此在这种情况下,文件要注意从 16 开始的行34
是更改内容的行,是第一个新内容(在我们的例子中为第 16 行)之后第 18 行的结果,所以 16 + 18 = 3481,$
是要删除的尾随行,$
意思是最后一行,81 是不需要的尾随行的第一行(在 80 之后)。