Awk, sed kullanarak belirli desenli satırların bir kısmını çıkarma


18

Awk / sed operatörleri ile ilgili bir sorum var. Aşağıdaki satırlar tekrarlanan büyük bir dosya var

Expression loweWallrhoPhi :  sum=-6.97168e-09
Expression leftWallrhoPhi :  sum=6.97168e-09
Expression lowerWallPhi :  sum=-5.12623e-12
Expression leftWallPhi :  sum=5.12623e-12
Expression loweWallrhoUSf :  sum=-6.936e-09
Expression leftWallrhoUSf :  sum=6.97169e-09
Expression lowerWallUSf :  sum=-5.1e-12
Expression leftWallUSf :  sum=5.12624e-12

Her durumda ayrı dosyada toplamdan sonra değer elde etmek istiyorum. Bir seferde bunu yapmak mümkün mü?

Yanıtlar:


26

Grep komutuyla:

grep -oP 'sum=\K.*' inpufile > outputfile

önceden eşleşen karakterleri yok saymak için kullanılan -P(perl-regexp) parametre destekli grep \K.

Awk komutu ile:

awk -F"=" '{print $NF}' inputfile > outputfile

Awk NF, bir kayıt / satırdaki toplam alan sayısını verir. Bunun son değeri bir kayıt / satırdaki son alan numarasıdır.

Sed komutu ile:

sed 's/^.*sum=//' inpufile > outputfile

^.*=sum.*satır başlangıcı ( ^) ile son karakter ( ) arasındaki tüm karakterleri ( ) sum=boşluk karakteriyle değiştir.

Sonuç:

-6.97168e-09
6.97168e-09
-5.12623e-12
5.12623e-12
-6.936e-09
6.97169e-09
-5.1e-12
5.12624e-12

Her değeri ayrı bir dosyaya kaydetmek istiyorsanız, yukarıdaki komutları while döngüsüne kullanın:

while read line; do
    echo "$line" | grep -oP 'sum=\K.*'     > $(echo "$line" |awk '{print $2}');
   #echo "$line" | awk -F"=" '{print $NF}' > $(echo "$line" |awk '{print $2}');
   #echo "#line" | sed 's/^.*sum=//'       > $(echo "$line" |awk '{print $2}');
done < file

Bu değer içerir sum=ve bundan sonraki değerle aynı değildirsum=
Anthon

OP toplamdan sonra değeri istiyor, ayrıca NF'nin garip tanımının da korkunç olduğunu söylüyor.

1
Bu çok iyi bir cevap tamamlamak için ayrıca kullanabilirsiniz cut: cut -d'=' -f2 file.
fedorqui

Bu çok iyi bir cevap. Bunu sevdim. Teşekkür ederim.
Jaffer Wilson

6

Yalnızca sonradan değer almak istediğiniz soruyu doğru şekilde =anlarsam ve bu değerleri ikinci alana (?) Dayalı olarak ayrı dosyalarda depolarsam. Eğer haklıysam böyle bir şey dene:

$ awk -F'[ =]' '{print $6>"file_"$2".txt"}' file

Sonuç:

$ ls -1
  file_leftWallPhi.txt
  file_leftWallUSf.txt
  file_leftWallrhoPhi.txt
  file_leftWallrhoUSf.txt
  file_loweWallrhoPhi.txt
  file_loweWallrhoUSf.txt
  file_lowerWallPhi.txt
  file_lowerWallUSf.txt

$ cat  file_leftWallPhi.txt
  5.12623e-12

@KasiyA GNU awk 4.0.2 ile sorununuzu yeniden oluşturamıyorum. Cevabımdaki komut da -cseçenekle çalışır ( awkGNU uzantılarının devre dışı bırakıldığı geleneksel UNIX ile uyumluluk modu ). Lütfen orijinal soru düzenlenirken ve boş satırlar silinirken girdi dosyasını güncellediğinizden emin olun.
jimmij

1

Tarafından yapabilirsin sed

sed -E 's/^.* (\S+)\s*:.*=(\S+)/echo "\2" > "\1".txt/' file | bash

Senaryo satırda iki parça bulur:

  1. boşluklar arasında ve :ve bazı (0'dan fazla) boşluk olmayan simgeler içermelidir;
  2. bazı (0'dan fazla) boşluk olmayan simgeler =;

ve borudan aktarılan yürütme komutundan biçimlendirin bash


Çok daha çok yönlü bir cevap.
duanev
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.