简体   繁体   English

使用sed在文本文件中移动匹配行

[英]Moving matching lines in a text file using sed

I am trying to follow the post 我正在努力关注这篇文章

How to move specified line in file to other place with regexp match (bash script)? 如何使用regexp匹配(bash脚本)将文件中的指定行移动到其他位置?

to my example file 到我的示例文件

asdasd0
-SRC_OUT_DIR = /a/b/c/d/e/f/g/h
asdasd2
asdasd3
asdasd4
DEFAULTS {
asdasd6

The final output should look like 最终输出应该是这样的

asdasd0
asdasd2
asdasd3
asdasd4
DEFAULTS {
-SRC_OUT_DIR = /a/b/c/d/e/f/g/h
asdasd6

I have tried the following 我尝试了以下内容

sed "/-SRC_OUT_DIR.*/d;/DEFAULTS { /a"$(sed -n '/-SRC_OUT_DIR.*/p' test.txt)  test.txt`

but it is not working. 但它不起作用。 I get the following output 我得到以下输出

sed:can't read =: No such file or directory
sed:can't read "/a/b/c/d/e/f/g": No such file or directory
asdasd0
asdasd2
asdasd3
asdasd4
DEFAULTS {
-SRC_OUT_DIR
asdasd6

I am also wondering why can't I use \\1 , \\2 to print the line that needs to be moved. 我也想知道为什么我不能使用\\1\\2打印需要移动的行。 I tried that but it prints nothing. 我试过了,但没有打印。 How would I write a sed command if I need to move multiple matching lines to different places in the file? 如果我需要将多个匹配行移动到文件中的不同位置,我将如何编写sed命令?

You could store the matching line in the hold space, delete it and then append the hold space to the line after which you want to insert: 您可以将匹配行存储在保留空间中, 删除 ,然后保留空间附加到要插入的行之后:

$ sed '/^-SRC_OUT_DIR/{h;d;};/^DEFAULTS {/G' infile
asdasd0
asdasd2
asdasd3
asdasd4
DEFAULTS {
-SRC_OUT_DIR = /a/b/c/d/e/f/g/h
asdasd6

While you ask a sed solution I would propose to use awk for this. 当你问一个sed解决方案时,我会建议使用awk Using an ugly nesting of a multitude of sed commands is not really recommended. 不建议使用大量sed命令的丑陋嵌套。 Especially because you read your file twice. 特别是因为你读了两次文件。

Here is an awk 这是一个awk

awk '/SRC_OUT_DIR/{t=$0;next}1;/DEFAULTS/{print t}' file

How does it work? 它是如何工作的?

awk will read your file line by line. awk将逐行读取您的file Per line, it will do the following three commands one after the other: 每行,它将一个接一个地执行以下三个命令:

  1. /SRC_OUT_DIR/{t=$0;next} : if the line contains a substring matching SRC_OUT_DIR , then store the line in a variable t and move to the next line (don't execute 2 and 3) /SRC_OUT_DIR/{t=$0;next}如果该行包含与SRC_OUT_DIR匹配的子字符串,则将该行存储在变量t并移至next行(不执行2和3)
  2. 1 : default action: print the line 1默认动作:打印行
  3. /DEFAULTS/{print t} : if the current line contains the substring DEFAULTS , print the line stored in variable t /DEFAULTS/{print t}如果当前行包含子字符串DEFAULTS ,则打印存储在变量t的行

If you have multiple lines to move (this only moves downwards): 如果你有多条线要移动(这只是向下移动):

awk '/pattern1/ {t[1]=$0;next}
     /pattern2/ {t[2]=$0;next}
     /pattern3/ {t[3]=$0;next}
     /target3/ { print t[3] }
     1
     /target1/ { print t[1] }
     /target2/ { print t[2] }' file

note that pattern3 will be printed before target3 . 请注意, pattern3将在target3之前target3

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM