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?

Pimpalgaonkar Hrushikesh
sumber

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
αғsнιη
sumber
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
jimmij
sumber
@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

Costas
sumber
Jawaban yang jauh lebih fleksibel.
duanev