2017-01-26 70 views
2

我有一個腳本,輸出文件路徑(通過查找):在bash中,如何對包含數字的字符串進行排序?

/foo/bar/example/foo/bar/example/foo-bar-example/1.2.3-something16 
/foo/bar/example/foo/bar/example/foo-bar-example/1.2.3.4-something1 
/foo/bar/example/foo/bar/example/foo-bar-example/1.2-something5 
/foo/bar/example/foo/bar/example/foo-bar-example/1.2.3.4-something2 
/foo/bar/example/foo/bar/example/foo-bar-example/1.2.3.4-something10 

如何列出他們猛砸,使他們在基於在到底有多少,也不管版本(上升的數字順序1.2,1.2.3或1.2.3.4)

ps:something部分最終可以包含短劃線。

所需的輸出:

/foo/bar/example/foo/bar/example/foo-bar-example/1.2.3.4-something1 
/foo/bar/example/foo/bar/example/foo-bar-example/1.2.3.4-something2 
/foo/bar/example/foo/bar/example/foo-bar-example/1.2-something5 
/foo/bar/example/foo/bar/example/foo-bar-example/1.2.3.4-something10 
/foo/bar/example/foo/bar/example/foo-bar-example/1.2.3-something16 

我使用的臨時標記字符分隔的到底有多少,但它在我的情況複雜一點點。

回答

4

末提取數量,在前面加上它的所有線路,排序數字和最後刪除號碼:

sed -r 's/(.*)([^0-9])([0-9]+)$/\3\1\2\3/' file | sort -n | sed 's/^[0-9]*//' 

隨着你的輸入,這將返回:

/foo/bar/example/foo/bar/example/foo-bar-example/1.2.3.4-something1 
/foo/bar/example/foo/bar/example/foo-bar-example/1.2.3.4-something2 
/foo/bar/example/foo/bar/example/foo-bar-example/1.2-something5 
/foo/bar/example/foo/bar/example/foo-bar-example/1.2.3.4-something10 
/foo/bar/example/foo/bar/example/foo-bar-example/1.2.3-something16 

我覺得這個我這是Schwartzian transform


通過片:

$ sed -r 's/(.*)([^0-9])([0-9]+)$/\3\1\2\3/' a 
16/foo/bar/example/foo/bar/example/foo-bar-example/1.2.3-something16 
1/foo/bar/example/foo/bar/example/foo-bar-example/1.2.3.4-something1 
5/foo/bar/example/foo/bar/example/foo-bar-example/1.2-something5 
2/foo/bar/example/foo/bar/example/foo-bar-example/1.2.3.4-something2 
10/foo/bar/example/foo/bar/example/foo-bar-example/1.2.3.4-something10 
#^ 
#note the numbers here 

$ sed -r 's/(.*)([^0-9])([0-9]+)$/\3\1\2\3/' a | sort -n 
1/foo/bar/example/foo/bar/example/foo-bar-example/1.2.3.4-something1 
2/foo/bar/example/foo/bar/example/foo-bar-example/1.2.3.4-something2 
5/foo/bar/example/foo/bar/example/foo-bar-example/1.2-something5 
10/foo/bar/example/foo/bar/example/foo-bar-example/1.2.3.4-something10 
16/foo/bar/example/foo/bar/example/foo-bar-example/1.2.3-something16 
                #^
                # now it is ordered 

$ sed -r 's/(.*)([^0-9])([0-9]+)$/\3\1\2\3/' a | sort -n | sed 's/^[0-9]*//' 
/foo/bar/example/foo/bar/example/foo-bar-example/1.2.3.4-something1 
/foo/bar/example/foo/bar/example/foo-bar-example/1.2.3.4-something2 
/foo/bar/example/foo/bar/example/foo-bar-example/1.2-something5 
/foo/bar/example/foo/bar/example/foo-bar-example/1.2.3.4-something10 
/foo/bar/example/foo/bar/example/foo-bar-example/1.2.3-something16 
+1

啊,我只是注意到已發佈類似的答案++ – anubhava

1

如果你能確保你將永遠不會在你的文件中的「#」字符,你可以嘗試:

sed -e 's/something/#/g' filename.txt | sort -t# -k2 -n | sed -e 's/#/something/g' 
+0

感謝。它的工作.. – Daniel

3

您可以使用此sed + sort + awk

sed -E 's/.*[^0-9]([0-9]+)$/\1 &/' file | sort -n | awk '{print $2}' 

/foo/bar/example/foo/bar/example/foo-bar-example/1.2.3.4-something1 
/foo/bar/example/foo/bar/example/foo-bar-example/1.2.3.4-something2 
/foo/bar/example/foo/bar/example/foo-bar-example/1.2-something5 
/foo/bar/example/foo/bar/example/foo-bar-example/1.2.3.4-something10 
/foo/bar/example/foo/bar/example/foo-bar-example/1.2.3-something16 
+1

酷!這更簡潔,做得好。在路徑中包含空格的情況下,可能值得把數字放在開頭,然後說'cut -d''-f2'從第二個字段打印。 – fedorqui

+0

好點@fedorqui ..謝謝 – anubhava

相關問題