Satır bloklarını sıralama


12

4n satır içeren bir dosya var. İşte 8 satır içeren bir alıntı

6115 8.88443
6116 6.61875
6118 16.5949
6117 19.4129
6116 6.619 
6117 16.5979 
6118 19.4111
6115 8.88433  

Ne yapmak istiyorum her blok ilk sütuna göre 4 satırdan oluşan bir blok sıralamak olduğunu. Alıntı için çıktı aşağıda gösterildiği gibi olmalıdır.

6115 8.88443
6116 6.61875
6117 19.4129
6118 16.5949
6115 8.88433 
6116 6.619 
6117 16.5979 
6118 19.4111 

Yanıtlar:


16

Seçeneklerden biri, her N satırına bir başlangıç ​​seri numarası öneki eklemek için kullanmaktır (sizin durumunuzda N = 4). Ardından öneki birincil sıralama sütunu olarak besleyin sort.

N = 4 ile örnek:

awk '{print int((NR-1)/4), $0}' file.txt | sort -n -k1,1 -k2,2 | cut -f2- -d' '

7

Bu bir tane ise ve python, perl veya awk öğrenmek istemiyorsanız, temel splitve sortkomutlarla gidebilirsiniz .

Öncelikle dosyayı 4 satır parçasına bölün ve şu -l seçeneği kullanın:

split -a 6 -l 4 input_file my_prefix_
for fn in my_prefix_*; do
    sort -n -o $fn $fn
done
cat my_prefix_* > output_file
rm my_prefix_*

sort -nİlk sütundaki (1234 önce 999) sayısal değerine göre sıralar. -a 626 ^ 6 * 4 satırlı bir dosya ile ilgilenmelidir. my_prefix_çalıştığınız dizine özgü bir şey olmalıdır.


3

Perl ile yapabilirsiniz:

perl -nle '
   push @a,$_;
   unless($. % 4){
       print join "\n",sort {$a <=> $b} @a; # Sort @a, and print its contents
       @a = (); # Empty @a to start a new block
   }
' your_file

Bu nasıl çalışır?

  • -n-> her giriş satırı için kodu çalıştırın (ve geçerli satırı girin $_)
  • -l -> herhangi birinin çıktısına yeni satır ekleyin print
  • -e -> aşağıdaki dizeyi Perl kodu olarak yürütün
  • Her satır diziye eklenir @a.
  • $.geçerli satır numarasını tutar ve bu sayı sıfır modulo 4 ile uyumlu değilse, çalışmaya devam ederiz. Bu ise bir sıfır modülo 4 uygun bir şekilde, kimin numarası 4 (a bloğun uç) bir katı olan bir çizgi, bu durumda, bir nevi girdilerinde ulaşmış @asayısal artan düzende ve sıralanmış bir dizi girişleri baskı standart çıktıya yeni satırla katılır.

2

Bourne benzeri bir kabuk kullanarak,

while read a ; do                                           # Try reading a line.
    read b ; read c ; read d                                # OK, read 3 more.
    printf '%s\n%s\n%s\n%s\n' "$a" "$b" "$c" "$d" | sort -n # Sort them.
done < data

2

İşte bazı "saf" awkçözümler:

Dizinler her zaman örnek verilerinizde olduğu gibi aynı artan tamsayı dizisi (6115-6119) ise, algoritmik bir "kısayol" kullanabilirsiniz:

awk '{a[$1]=$0} !(NR%4){for(i=6115;i<6119;print a[i++]);}'

Bu yapar

  • aDizine, 6115-6119 dizin konumlarında dağıtılan tüm satırları ekleyin
  • Her 4. satırda ( !(NR%4)), istediğiniz sırada yazdırmak için dizi içerikleri arasında gezinin.

Sayısal dizinleriniz her zaman dört dizinse, ancak artan bir tam sayı dizisi değilse, sıralamanız gerekir:

awk '{a[$1]=$0} !(NR%4){asort(a,b); for(i=1;i<5;print b[i++]);}'

Not: Bu GNU awk ile, diğerleri desteklemeyebilir asort.


Dört bloktan her biri farklı sayısal kimliklere sahip olabilirse:

awk '{a[$1]=$0} !(NR%4){asort(a); for(i=1;i<5;print a[i++]); delete a}'

Not: @Gilles'ın kendi kendine yanıtından (+2)delete gelen TIL, bu (henüz) POSIX değil, evrensel olarak desteklenmektedir .


Aşağıdakileri doğru şekilde kullanan bir sürüm delete:

awk '{a[$1]=$0} !(NR%4){asort(a); for(i=1;i<5;delete a[i++]){print a[i]}}'

Daha fazla bellek ve boyut kullanan, silinmeyen bir sürüm:

awk '{a[n][$1]=$0} !(NR%4){asort(a[n]); for(i=1;i<5;print a[n][i++]); n++}

1

R ile temiz bir çözüm elde edebilirsiniz. Yukarıdaki tablo "table.txt" adlı bir dosyadaysa, aşağıdaki adımları uygulayın. İstenen sonuç "tableout.txt" dosyasında olacaktır.

> x = read.table("table.txt", col.names=c("a", "b"))
> x
     a        b
1 6115  8.88443
2 6116  6.61875
3 6118 16.59490
4 6117 19.41290
5 6116  6.61900
6 6117 16.59790
7 6118 19.41110
8 6115  8.88433
> x["index"] = c(rep(1, 4), rep(2, 4))
> x
     a        b index
1 6115  8.88443     1
2 6116  6.61875     1
3 6118 16.59490     1
4 6117 19.41290     1
5 6116  6.61900     2
6 6117 16.59790     2
7 6118 19.41110     2
8 6115  8.88433     2     
> xord = x[with(x, order(index, a)), ]
> xord
     a        b index
1 6115  8.88443     1
2 6116  6.61875     1
4 6117 19.41290     1
3 6118 16.59490     1
8 6115  8.88433     2
5 6116  6.61900     2
6 6117 16.59790     2
7 6118 19.41110     2
> write.table(xord[,1:2], "tableout.txt", row.names=FALSE, col.names=FALSE)

Ayrıca bkz. Veri çerçevesini R sütunlarına göre sıralama .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.