Ekstraksi bagian dari garis dengan pola tertentu menggunakan awk, sed


18

Saya punya pertanyaan tentang operator awk / sed. Saya memiliki file besar yang telah mengikuti serangkaian garis diulang

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

Saya ingin mengekstraksi nilai setelah menjumlahkan dalam setiap kasus dalam file terpisah. Apakah mungkin untuk melakukannya sekaligus?

Jawaban:


26

Dengan perintah grep:

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

grep dengan -Pdukungan parameter (perl-regexp) \K, yang digunakan untuk mengabaikan karakter yang sebelumnya cocok.

Dengan perintah awk:

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

Awk NFmemberi Anda jumlah total bidang dalam catatan / baris. Jadi nilai terakhir dari itu adalah nomor bidang terakhir dalam catatan / baris.

Dengan perintah sed:

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

^.*=sumganti semua karakter ( .*) antara mulai dari baris ( ^) dan karakter terakhir ( sum=) dengan char spasi putih.

Hasil:

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

Jika Anda ingin menyimpan setiap nilai ke file terpisah, gunakan perintah di atas ke dalam loop sementara:

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

Itu termasuk sum=dan yang tidak sama dengan nilai setelahnyasum=
Anthon

OP menginginkan nilai setelah penjumlahan, juga deskripsi awk NF yang buruk.

1
Untuk melengkapi jawaban yang sangat baik ini, Anda juga dapat menggunakan cut: cut -d'=' -f2 file.
fedorqui

Ini jawaban yang sangat bagus. Aku menyukainya. Terima kasih.
Jaffer Wilson

6

Jika saya benar memahami pertanyaan yang ingin Anda dapatkan hanya setelah nilai =, dan menyimpan nilai-nilai ini dalam file terpisah, berdasarkan bidang kedua (?). Jika saya benar coba sesuatu seperti ini:

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

Hasil:

$ 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 Saya tidak bisa mereproduksi masalah Anda dengan GNU awk 4.0.2. Perintah dari jawaban saya juga berfungsi dengan -copsi (mode kompatibilitas dengan UNIX tradisional di awkmana ekstensi GNU dinonaktifkan). Pastikan Anda telah memperbarui file input karena pertanyaan awal telah diedit dan baris kosong dihapus.
jimmij

1

Anda bisa melakukannya dengan sed

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

Script mencari dua bagian dalam baris:

  1. antara spasi dan :dan harus mengandung beberapa (lebih dari 0) simbol non-spasi;
  2. beberapa (lebih dari 0) simbol non-spasi setelah =;

dan format dari perintah eksekusi yang ditransfer melalui pipa ke bash


Jawaban yang jauh lebih fleksibel.
duanev
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.