2017-09-02 98 views
2

嗨同伴溢出用戶。Bash - 對文件中的行進行排序的範圍

我很想知道如何通過Linux中的終端命令對文件中的一系列行進行排序。

例如,在test.sh文件:

g++ -o test.out \ 
Main.cpp \ 
Framework.cpp \ 
Sample.cpp \ 
Blub.cpp \ 
-std=c++14 -lboost 

我如何排序從第二行到該文件中的倒數第二行(源文件名)。

所需的輸出:

g++ -o test.out \ 
Blub.cpp \ 
Framework.cpp \ 
Main.cpp \ 
Sample.cpp \ 
-std=c++14 -lboost 

(從2號線排序 - 5)

感謝您的關注:)

回答

3

頭,GNU sed和尾:

(head -n 1 test.sh; sed -n '2,${/\\/p}' test.sh | sort; tail -n 1 test.sh) > test_new.sh 

輸出:

 
g++ -o test.out \ 
Blub.cpp \ 
Framework.cpp \ 
Main.cpp \ 
Sample.cpp \ 
-std=c++14 -lboost 
+0

但是如何將輸出發送到文件中。我希望這個文本在文件中。我必須在每個命令之後將其回顯到文件中嗎? –

+0

我已經更新了我的答案。 – Cyrus

+0

不錯,謝謝你的隊友,如果我在最後加上「&& mv test_new.sh test.sh」它甚至會保留它的名字。 –

1

當你正在編輯vi的文件,你的光標在Blub.cpp,你可以輸入

:.,+3 !sort 

或者當你不想算上線,使用另一個範圍:

:.,/std/-1 !sort 

編輯: 從命令行:

ex -c'2,5 sort|w|q' test.sh 
+0

謝謝你的回答。但我想在終端中作爲bash命令本身執行此操作。 –

+0

請參閱編輯命令行命令。 –

+0

編輯我的答案後,我看到@Kusalananda也發現這個'ex'。我們的答案是'ex -s -c'2,5 sort | x'file'。 –

6

排序使用ex行編輯:

$ cat file 
g++ -o test.out \ 
Sample.cpp \ 
Main.cpp \ 
Framework.cpp \ 
Blub.cpp \ 
-std=c++14 -lboost 

$ echo 'x' | ex -s -c '2,5!sort' file 

$ cat file 
g++ -o test.out \ 
Blub.cpp \ 
Framework.cpp \ 
Main.cpp \ 
Sample.cpp \ 
-std=c++14 -lboost 

ex -s -c '2,5!sort'會把ex在批處理模式(-s)並應用命令2,5!sort輸入文件。這將通過執行外部sort實用程序與給定範圍內的行,然後用sort的輸出替換相同的行來對第2行到第5行進行排序。

echo 'x'用於發送x命令到ex這將使它保存其修改的緩衝區並退出。如果沒有這個,您必須在終端上手動鍵入x,然後按輸入退出ex

這假定經典的ex(如在BSD中發現的)。如果你從一個Vim分佈有ex,你可以使用

$ ex -s -c '2,5 sort|x' file 

這在使用內部sort命令Vim的ex(相同的Vim :sort)。


的要求,在意見:

從2號線所有線下到第二個文件中使用BSD ex排序,最後一行:

$ echo 'x' | ex -s -c '2,$-1!sort' file 

,或者用Vim的ex

$ ex -s -c '2,$-1 sort|x' file 

範圍從2,52,$-1,即從第2行到「結尾減1」。


可惜sed不支持相同類型的操作。

+0

多數民衆贊成在一種方式來做到這一點,謝謝。 –

+0

我喜歡這個答案。謝謝+1。 – whoan

+0

有關如何在文件恰好具有多於/少於6行的情況下動態查找「倒數第二行」(本例中爲5)的任何想法?而像'wc -l'減1的東西可以工作,我想知道'ex'中是否有任何允許指定和/或查找下一行的內容? – markp

0
$ cat test.awk 
{ a[NR]=$0 } 
END { 
    print a[1] 
    lastline=a[NR] 
    delete a[1] 
    delete a[NR] 
    n=asort(a) 
    for (i = 1; i <= n; i++) { print a[i] } 
    print lastline 
} 
  • a[NR]=$0:文件的行加載到陣列a;使用行/記錄數(NR)作爲數組索引
  • END { ... }:一旦我們加載的所有入線陣列,應用以下命令對陣列...
  • print a[1]:印刷生產線1
  • lastline=a[NR]:保存最後一行在我們的變量lastline
  • delete a[#]:我們的數組中的其餘線路進行排序,分配(數組項目數線勒又名數:從數組
  • n=asort(a)刪除第一&最後一個行FT在數組)我們的變量n
  • for/print:打印線2 - 下一個到最後一行
  • print lastline:打印最後一行

現在運行對樣本文件:

$ awk -f test.awk test.sh 
g++ -o test.out \ 
Blub.cpp \ 
Framework.cpp \ 
Main.cpp \ 
Sample.cpp \ 
-std=c++14 -lboost 
相關問題