Извлечение части строк с определенным рисунком с помощью 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

-PПоддерживается grep с параметром (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:

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=
Anthon

OP хочет получить значение после суммы, а также то, что awk-описание NF ужасно.

1
Для того, чтобы завершить этот очень хороший ответ, вы также можете использовать cut: cut -d'=' -f2 file.
Федорки

Это очень хороший ответ. Мне нравится. Спасибо.
Джаффер Уилсон

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 отключены). Убедитесь, что вы обновили исходный файл, так как исходный вопрос был отредактирован, а пустые строки удалены.
Джимми

1

Вы можете сделать это, sed

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

Скрипт обнаруживает две части в строке:

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

и отформатировать его в команде выполнения, которая передается по каналу bash


Гораздо более универсальный ответ.
Duanev
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.