2012-11-23 158 views
3

在以下示例中,存在具有進行排序3個元素:形成單個單元如何對行組進行排序?

  1. 「[AAA]」和4線(總是4)在其下方。
  2. 「[kkk]」和它下面的4行(總是4)組成一個單元。
  3. 「[zzz]」和它下面的4行(總是4)組成一個單元。

只有以下這個圖案線的基團應該被排序;必須保留「[aaa]」之前和「[zzz]」第4行之後的任何內容。

來自:

This sentence and everything above it should not be sorted. 

[zzz] 
some 
random 
text 
here 
[aaa] 
bla 
blo 
blu 
bli 
[kkk] 
1 
44 
2 
88 

And neither should this one and everything below it. 

到:

This sentence and everything above it should not be sorted. 

[aaa] 
bla 
blo 
blu 
bli 
[kkk] 
1 
44 
2 
88 
[zzz] 
some 
random 
text 
here 

And neither should this one and everything below it. 
+0

多麼可怕的例子..你爲什麼對所有的部分都有相同的值?注意:我會使用'awk'。 –

+0

編輯:現在應該更容易理解。 – octosquidopus

+0

是的,在說明數據前後都是如此。祝你好運。 – shellter

回答

1

也許不是最快的:) [1],但它會做你想要什麼,我相信:

for line in $(grep -n '^\[.*\]$' sections.txt | 
       sort -k2 -t: | 
       cut -f1 -d:); do 
    tail -n +$line sections.txt | head -n 5 
done 

這裏的更好的一個:

for pos in $(grep -b '^\[.*\]$' sections.txt | 
      sort -k2 -t: | 
      cut -f1 -d:); do 
    tail -c +$((pos+1)) sections.txt | head -n 5 
done 

[1]第一個文件中的行數爲O(N^2),因爲它必須一直讀取每個節的節。第二個可以立即找到正確的字符位置,應該更接近O(N log N)。

[2]這需要你的話,總是有正好在每一節(頭加上四以下)五線,因此head -n 5。然而,用一個'['開始的下一行代碼來替換它是很容易的,以防萬一有必要。


保留的開始和結束需要多一點的工作:

# Find all the sections 
mapfile indices < <(grep -b '^\[.*\]$' sections.txt) 
# Output the prefix 
head -c+${indices[0]%%:*} sections.txt 
# Output sections, as above 
for pos in $(printf %s "${indices[@]}" | 
      sort -k2 -t: | 
      cut -f1 -d:); do 
    tail -c +$((pos+1)) sections.txt | head -n 5 
done 
# Output the suffix 
tail -c+$((1+${indices[-1]%%:*})) sections.txt | tail -n+6 

您可能希望做出來的一個函數,或一個腳本文件,sections.txt改變整個$ 1

+0

它排序,但錯誤地丟棄頁眉和頁腳。他們不應該受到程序的影響。 – octosquidopus

+0

一個保持頁眉和頁腳的方式(另一種方法是首先剝奪他們和它們添加回底。) – rici

1

假設其他線路不包含在他們[

header=`grep -n 'This sentence and everything above it should not be sorted.' sortme.txt | cut -d: -f1` 
footer=`grep -n 'And neither should this one and everything below it.' sortme.txt | cut -d: -f1` 

head -n $header sortme.txt #print header 

head -n $((footer - 1)) sortme.txt | tail -n +$((header + 1)) | tr '\n[' '[\n' | sort | tr '\n[' '[\n' | grep -v '^\[$' #sort lines between header & footer 
#cat sortme.txt | head -n $((footer - 1)) | tail -n +$((header + 1)) | tr '\n[' '[\n' | sort | tr '\n[' '[\n' | grep -v '^\[$' #sort lines between header & footer 

tail -n +$footer sortme.txt #print footer 

供應的目的。

注意,主排序工作僅由4個命令來完成。其他行是預留頁眉&頁腳。

我還假設,頭&第一「[第]」沒有其他線之間。

+2

沒用使用'cat'發現! –

+0

^^對不起,那是我正在測試。忘了改變它。 – anishsane

0

這可能會爲你工作(GNU sed的&排序):

sed -i.bak '/^\[/!b;N;N;N;N;s/\n/UnIqUeStRiNg/g;w sort_file' file 
sort -o sort_file sort_file 
sed -i -e '/^\[/!b;R sort_file' -e 'd' file 
sed -i 's/UnIqUeStRiNg/\n/g' file 

排序文件將在file和原文件中file.bak

這將顯示以排序順序排列的所有以[開頭的行和以下4行。

UnIqUeStRiNg可以是不包含換行符的任何唯一字符串,例如, \x00

+0

你忘了頁眉和頁腳...'這句話,一切上面不應該從您提供的頁眉和頁腳未排序示例數據sorted.' – anishsane

+0

@anishsane。但是,如果該文件的這些部分可能包括開頭的行'[...]'那麼sed命令可以更具體,即'/^\ [\(AAA \ | \ KKK \ | ZZZ \)\]!/ B ' – potong