通过 bash 对子字符串进行内联重新排序

Inline reordering of substrings via bash

假设一个文本文件包含特定的行,其词序应该改变。单词(子字符串)由单个空格分隔。要更改的行可以通过它们的第一个字符(例如,“>”)来标识。

# cat test.txt
>3 test This is
foo bar baz
foo bar qux
>2 test This is
foo bar baz
>1 test This is
foo bar qux

您会使用什么命令(可能在 awk 中)对以关键字符开头的所有行应用相同的排序过程?

# cat test.txt | sought_command
>This is test 3
foo bar baz
foo bar qux
>This is test 2
foo bar baz
>This is test 1
foo bar qux

按照你的例子,是这样的:

awk '~"^>" {sub(">","",);print ">",,,;next} {print}' test.txt

这是您可以使用 awk 实现的一种方法:

awk 'sub(/^>/, "") { print ">", , , ; next } 1' file

sub returns true (1) 当它进行替换时。最后的1是最短的true条件,触发默认动作{ print }.

最适合在单行上进行简单替换的工具是 sed:

$ sed -E 's/>([^ ]+)( [^ ]+ )(.*)/>/' file
>This is test 3
foo bar baz
foo bar qux
>This is test 2
foo bar baz
>This is test 1
foo bar qux

Awk 是做更多事情的正确工具 complicated/interesting。请注意,与您目前收到的 awk 解决方案不同,上面的解决方案将继续工作 if/when 您在一行中有超过 4 "words",例如:

$ cat file
>3 test Now is the Winter of our discontent
foo bar baz
foo bar qux
>2 test This is
foo bar baz
>1 test This is
foo bar qux

$ sed -E 's/>([^ ]+)( [^ ]+ )(.*)/>/' file
>Now is the Winter of our discontent test 3
foo bar baz
foo bar qux
>This is test 2
foo bar baz
>This is test 1
foo bar qux

$ awk 'sub(/^>/, "") { print ">", , , ; next } 1' file
>Now is test 3
foo bar baz
foo bar qux
>This is test 2
foo bar baz
>This is test 1
foo bar qux