2016-07-28 27 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 
相關問題