Birden çok satır içeren metin dosyalarını satır olarak sıralama


14

Bu biçimde bir metin dosyası var:

####################################
KEY2
VAL21
VAL22
VAL23
VAL24
####################################
KEY1
VAL11
VAL12
VAL13
VAL14
####################################
KEY3
VAL31
VAL32
VAL33
VAL34

Ben bu dosyayı KEYsatır sıralamak istiyorum ve sonuç olarak sıralı sonuç olmalıdır sonuç ile sonraki 4 satır tutmak:

####################################
KEY1
VAL11
VAL12
VAL13
VAL14
####################################
KEY2
VAL21
VAL22
VAL23
VAL24
####################################
KEY3
VAL31
VAL32
VAL33
VAL34

Bunu yapmanın bir yolu var mı?


5
yok Çapraz yazı lütfen
Zanna

@Zanna: Bence bu ikisinin birbiriyle çok fazla örtüşmesi nedeniyle unix ve askubuntu bölümleri için bir dışlama var! Sanırım bunu
unix'in

2
ilgili meta soru burada AU mod tarafından sorulmuştur :) Ask Ubuntu'ya çapraz sorulan sorular nasıl ele alınmalıdır?
Zanna

@RYN Sorun örtüşme olmaz, aslında pek çok SE sitesi çakışıyor, ancak cevap veren kişilerin diğer sitedeki cevaplar hakkında bilgi sahibi olmayabilir.
phk

Yanıtlar:


13

msort(1)çok satırlı kayıtlara sahip dosyaları sıralayabilmek için tasarlanmıştır. İsteğe bağlı bir GUI'nin yanı sıra normal ve insanlar için kullanılabilir bir komut satırı sürümüne sahiptir. (En azından, el kitaplarını dikkatlice okumayı ve örnekler aramayı seven insanlar ...)

AFAICT, kayıtlarınız için rastgele bir desen kullanamazsınız, bu nedenle kayıtlarınız sabit boyutlu değilse (karakter veya satır değil bayt cinsinden). boş satırlarla ayrılmış satır blokları olan kayıtlar için msortbir -bseçenek vardır.

Girdilerinizi -bher şeyden önce boş bir satır koyarak ###...(birincisi hariç) oldukça kolay çalışacak bir formata dönüştürebilirsiniz .

Varsayılan olarak, stderr'deki istatistikleri yazdırır, bu yüzden en azından tüm girdinin tek bir kayıt olduğunu düşündüğü için sıralanmadığı zamanı söylemek kolaydır.


msortverileriniz üzerinde çalışır. sedKomut her bir yeni satır başa ekler #+1. hat dışında hat -wsıralar bütün kaydı (sözlük sırasında). Bir kaydın hangi kısmını anahtar olarak kullanacağınızı seçmek için seçenekler var, ancak onlara ihtiyacım yoktu.

Ayrıca ekstra satırsonu sıyırdı.

$ sed '2,$ s/^#\+/\n&/' unsorted.records | msort -b -w 2>/dev/null 
####################################
KEY1
VAL11
VAL12
VAL13
VAL14

####################################
KEY2
VAL21
VAL22
VAL23
VAL24

####################################
KEY3
VAL31
VAL32
VAL33
VAL34

Bunu -r '#'kayıt ayırıcı olarak kullanmakta şansım olmadı . Tüm dosyanın tek bir kayıt olduğunu düşünüyordu.


çok teşekkür ederim; msortçok kullanışlı; teşekkürler (hakkında -rgörünüyor çünkü birden fazla # kullandığım -dve işe yaradı
RYN

güzel! (+1) msort -qwr '#' ex benim için çalışıyor (çıktı ayırıcıyı iyi
yönetiyor

9

Bir çözüm, ilk önce bir blok içindeki satır beslemelerini seçtiğiniz kullanılmayan bir karakterle (aşağıdaki örnekte '|') değiştirmek, sonucu sıralamak ve seçilen ayırıcıyı orijinal satır beslemesine geri döndürmektir:

sed -e 'N; N; N; N; N; s/\n/|/g' file.txt \
| sort -k2,2 -t\| \
| sed 's/|/\n/g'

1
Teşekkürler; Bu çalışır ama veri de kirli olduğunda özel olarak çok kirli! anahtardan sonraki satırlar 100 ise, ;Noraya 100 koymam gerekir ve metnin kendisinde kullanılmayan bir karakteri bulmak zorlaşabilir; çok iyi sortya da awk, ... çok satırlı sıralama yapabilmek
RYN

5
perl -0ne 'print sort /(#+[^#]*)/g' file.txt
  • perl -0 tüm dosyayı karıştırır
  • /(....)/g kayıtları eşleştir ve çıkar
  • print sort ... sırala ve yazdır

2

Bir KEYbölümdeki herhangi bir sayıda satırla çalışması gereken başka bir yol :

# extract delimiter
delim=$(head -n1 <infile)
sed '/#/d;/KEY/h;G;s/\n/\x02/' infile | nl -ba -nrz -s $'\002' | sort -t $'\002' -k3 -k1,1 |
cut -d $'\002' -f2 | sed '/KEY/{x;s/.*/'"${delim}"'/;G}'

Bu, sınırlayıcıyı bir değişkene kaydederek çalışır (daha sonra onu girişten kaldırmak için). Daha sonra, KEY*ayırıcı olarak düşük bir ascii karakterini (girişinizde olması muhtemel değildir) kullanarak karşılık gelen bölümdeki her satıra ekler ve daha sonra aynı ayırıcıyı kullanarak ntüm inesleri çıkarır l. O zaman bu sadece sort3. ve 1. sahaya cutgirmek ve orta sütunu bağlamak ve ardından bir final yoluyla sınırlayıcıları geri yüklemek meselesidir sed. Yukarıdakilerle birlikte KEY12daha önce sıralanacağını unutmayın, bu KEY2nedenle sortkomutu ihtiyaçlarınıza göre ayarlayın .


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.