2017-08-02 68 views
2
評論

說我有一個sort_me.txt文件:排序文件高達Linux的

a 
d 
b 
c 
f 
g 

// dont mix the two sections 

a 
c 
d 
b 

的那一刻,我做明顯sort sort_me.txt和獲取:

a 
a 
b 
b 
c 
c 
d 
d 
// dont mix the two sections 
f 
g 

哪當然不是我想要的,我想要的是它將評論前的部分和評論後的部分分開排序。

隨着期望的結果爲:

a 
b 
c 
d 
f 
g 
// dont mix the two sections 
a 
b 
c 
d 

回答

1

我想使用csplit分裂段成單獨的文件,當然應該有更容易的方式來實現:

#!/bin/bash 

linenum=`csplit -z $1 /^$/ {*}` 
count=0 
output='' 
for line in $linenum 
    do 
    file=`printf "xx%.2d" $count` 
    sorted=`cat $file | sort` 
    output="$output$sorted" 
    ((count++)) 
    done 
echo "$output" 

注意csplit將爲每個部分的臨時文件,所以你可能會更新上面的腳本來取消每個鏈接,即unlink $file

2

Perl來救援:

perl -007 -nE ' 
    @sections = map [ split /\n/ ], split m{^(?=//)}m; 
    say join "\n", sort @$_ for @sections; 
' -- file 
  • -007讀取整個文件,而不是逐行處理它(只能如果文件ISN 't巨大)
  • @sections是一個數組數組,外部數組對應於部分,內部數組對應於個別行

如果文件過大,不適合到內存中,你需要逐行處理它,只存儲當前部分:

perl -ne ' 
    sub out { print sort @lines; @lines = $_ } 
    if (m{^//}) { out() } 
    else { push @lines, $_ } 
    END { out() } 
' -- file 
1

沒有perl的,你可以像腳本做這個:

#!/bin/bash 

FILE_NAME=$1 

SEPARATOR='//' 

LINE_NUMBER=`grep -n $SEPARATOR $FILE_NAME | cut -f1 -d:` 

FILE_LENGTH=`wc -l $FILE_NAME | cut -f1 -d\s` 

head -$(($LINE_NUMBER-1)) $FILE_NAME | sort 

grep $SEPARATOR $FILE_NAME 

tail -$(($FILE_LENGTH-$LINE_NUMBER-1)) $FILE_NAME | sort 

它搜索分隔線並逐個排列部分。當然,如果你有兩個以上的部分,它將無法正常工作。