如何将文本块和下一个第 n 行按照模式移动到文件末尾?

Lis*_*iso 3 string awk sed ed

我有这个 ssh 配置需要编辑。

\n
Host vps6\n   HostName 123.456.789.00\n   User dylan\n   Port 123\n\nHost vps4\n   HostName 123.456.789.00 \n   User dylan\n   Port 123\n\n# old server\n\nHost vps3-old\n   HostName 123.456.789.00\n   User dylan \n   Port 123\n
Run Code Online (Sandbox Code Playgroud)\n

我想将配置移至vps6文件末尾并追加-old其配置别名。生成的文件将是。

\n
Host vps4\n   HostName 123.456.789.00 \n   User dylan\n   Port 123\n\n# old server\n\nHost vps3-old\n   HostName 123.456.789.00\n   User dylan \n   Port 123\n\nHost vps6-old\n   HostName 123.456.789.00\n   User dylan\n   Port 123\n
Run Code Online (Sandbox Code Playgroud)\n

我设法使用这个 sed 命令 \xe2\x86\x92 来做到这一点sed \'/\'"vps4"\'/{N;N;N;N;H;$!d}; ${p;x;s/\'"vps4"\'/\'"vps4"\'-old/}\',不幸的是这在文件末尾给了我不需要的换行符。

\n
[tmp]$ sed \'/\'"vps6"\'/{N;N;N;N;H;$!d}; ${p;x;s/\'"vps6"\'/\'"vps6"\'-old/}\' config\nHost vps4\n   HostName 123.456.789.00\n   User dylan\n   Port 123\n\n# old server\n\nHost vps3-old\n   HostName 123.456.789.00\n   User dylan \n   Port 123\n\nHost vps6-old\n   HostName 123.456.789.00 \n   User dylan\n   Port 123\n\n[tmp]$ # See above me\n
Run Code Online (Sandbox Code Playgroud)\n

此外,我希望能够指定要移动的下 n 行(例如上面将被标记Host vps4,下 3 行将被移动到文件末尾)。我在网上搜索并发现执行此类任务的推荐工具是ed,但我还没有找到示例命令来完全执行我想要的操作。

\n

Rav*_*h13 5

使用您显示的示例,请尝试以下awk代码。

awk '
!NF && found{
  found=""
  next
}
/^Host vps6/{
  found=1
  line=$0"-old"
  next
}
found{
  val=(val?val ORS:"")$0
  next
}
!found
END{
  print ORS line ORS val
}
'  Input_file
Run Code Online (Sandbox Code Playgroud)

注意:如果您想将输出保存到Input_file本身,然后运行上面的程序,它将在终端上打印输出,一旦您对上面程序的结果感到满意,那么您可以附加 > temp && mv temp Input_file到上面的程序,以就地保存到Input_file中。

说明:为上述使用的代码添加详细说明。

awk '                      ##Starting awk program from here.
!NF && found{              ##Checking if line is empty AND found is SET then do following.
  found=""                 ##Nullifying found here.
  next                     ##next will skip all further statements from here.
}
/^Host vps6/{              ##If line starts from Host vps6 then do following.
  found=1                  ##Setting found here.
  line=$0"-old"
  next
}
found{                     ##If found is set then do following.
  val=(val?val ORS:"") $0  ##Creating val which is keep adding current line into it.
  next                     ##next will skip all further statements from here.
}
!found                     ##If found is NOT set then print that line.
END{                       ##Starting END block of this program from here.
  print ORS line ORS val   ##Printing ORS line ORS and val here.
}
'  Input_file              ##Mentioning Input_file name here. 
Run Code Online (Sandbox Code Playgroud)