2017-09-02 83 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 
相关问题