2016-07-28 41 views
0

假设一个文本文件包含应改变其顺序的特定行。单词(子字符串)由单个空格分隔。要改变的行可以通过它们的第一个字符(例如“>”)来标识。通过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 
+0

不懂的排序规则.. .. – Kent

+0

你有什么尝试?是否有一个更抽象的输入和输出定义,可以使重新排序规则更清晰? – l0b0

回答

2

这里是你可以用awk做这件事:

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

sub回报(1)时,它使替代。 1最后是最短的true条件,触发默认动作{ print }

+0

哇!与我的脚本相同,但优化! – AwkMan

1

根据你的榜样,像这样:

awk '$1~"^>" {sub(">","",$1);print ">"$3,$4,$2,$1;next} {print}' test.txt 
+0

谢谢。干净利落! –

+1

'〜'运算符用于regexp比较,所以表达式右边的是一个正则表达式,而不是一个字符串,所以应该用正则表达式分隔符,'/.../',而不是字符串分隔符, “......”'。当在正则表达式上下文中使用字符串分隔符时,awk必须分析字符串两次,首先将其转换为正则表达式,然后再次将其用作正则表达式,并且具有结果,包括要求将任何转义字符加倍。 '/ foo \ .bar /'vs'$ 0〜“foo \\。bar”'。所以你应该使用'$ 1〜/ ^> /',而不是'$ 1〜'^>“'。 –

+1

感谢您提供的信息@EdMorton !.感谢你知道我明白为什么我的花characters角色有问题。从'〜'运算符开始,我将使用'/../'。 – AwkMan

0

最适合于对个人行简单的替代工具是sed:

$ sed -E 's/>([^ ]+)([^ ]+)(.*)/>\3\2\1/' 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是什么更多的复杂的/有趣的工具。请注意,与awk的解决方案,您已经收到到目前为止上面会继续,如果/当你有一个以上的线路4“字”,例如工作:

$ 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/>([^ ]+)([^ ]+)(.*)/>\3\2\1/' 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 ">"$3, $4, $2, $1; 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 
相关问题