Витягування частини ліній за певним малюнком за допомогою awk, sed


18

У мене питання щодо операторів awk / sed. У мене великий файл, який повторює наступний набір рядків

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

Я хочу отримати значення після суми в кожному випадку в окремому файлі. Чи можливо це зробити за один раз?

Відповіді:


26

З командою grep:

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

grep з -Pпідтримкою параметра (perl-regexp) \K, який використовується для ігнорування раніше узгоджених символів.

З командою awk:

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

Awk NFдає вам загальну кількість полів у записі / рядку. Отже, останнє значення цього є останнім номером поля в записі / рядку.

З командою sed:

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

^.*=sumзамініть усі символи ( .*) між початком рядка ( ^) та останніми символами ( sum=) знаком пробілу.

Результат:

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

Якщо ви хочете зберегти кожне значення в окремому файлі, скористайтеся вищезазначеними командами в циклі часу:

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

Це включає в себе, sum=і це не те саме, що значення післяsum=
Антона

ОП хоче значення після суми, також, що awk опис NF є жахливим.

1
Для того, щоб завершити цей дуже хороший відповідь, ви також можете використовувати cut: cut -d'=' -f2 file.
fedorqui

Це дуже гарна відповідь. Мені це сподобалося. Дякую.
Джеффер Вілсон

6

Якщо я правильно розумію питання, після якого потрібно отримати лише значення =, і зберігаю ці значення в окремих файлах на основі другого поля (?). Якщо я маю рацію, спробуйте щось подібне:

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

Результат:

$ 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. Команда з моєї відповіді також працює з -cопцією (режим сумісності з традиційним UNIX, awkде розширення GNU вимкнено). Будь ласка, переконайтеся, що ви оновили вхідний файл, оскільки оригінальне запитання було відредаговано, а порожні рядки видалені.
jimmij

1

Ви можете це зробити за допомогою sed

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

Сценарій знаходить дві частини в рядку:

  1. між пробілами та :і має містити деякі (не більше 0) непробільних символів;
  2. деякі (більше 0) непробільні символи після =;

і формат від його у виконанні команди, яка передається через трубу до bash


Набагато більш універсальна відповідь.
дуанев
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.