#awk #sed
#awk #sed
Вопрос:
Я застрял с подходом, требующим разделения значения до /
и после /
Вот содержимое файла:
Min/Max Inference Time : 70 ms / 290 ms
Average Inference Time : 90 ms
Ожидаемый результат:
Min : 70
Max : 290
Вот что я пробовал:
cat scores.csv | awk '///' | sed 's/ms//g'| awk 'BEGIN{FS=":"}{print $2}'
Но я не знаю, как разделить значение до /
и после /
для ожидаемого результата выше.
Ответ №1:
Попробуйте awk с несколькими разделителями
$ echo "Min/Max Inference Time : 70 ms / 290 ms" |
awk -F"[/ ] " ' { print $1, ":", $(NF-3); print $2,":",$(NF-1) } '
Min : 70
Max : 290
$
ПРАВКА 1: FS не должна меняться
$ echo "Min/Max Inference Time : 70 ms / 290 ms" | awk -F: -v OFS=":" ' { split($1,a,"[ /] "); split($2,b,"ms|/"); print a[1],b[1]; print a[2],b[3] } '
Min: 70
Max: 290
$
ПРАВКА2:
$ awk -F: -v OFS=":" ' { if(///) { split($1,a,"[ /] "); split($2,b,"ms|/"); print a[1],b[1]; print a[2],b[3] } else { print } }' scores.csv
Min: 70
Max: 290
Average Inference Time : 90 ms
$
с помощью Perl,
$ perl -lne ' /(. ?)/(. ?)s . ?(d ). ?(d )/ ? print $1,": ",$3,"n",$2,": ",$4 : print ' scores.csv
Min: 70
Max: 290
Average Inference Time : 90 ms
$
Комментарии:
1. Я не хочу менять разделитель полей
:
, поскольку другие оценки зависят2. вы имеете в виду .. разделитель выходных данных?.. можете ли вы использовать дополнительные образцы?
3. Не осталось входных FS
:
4. Ожидаемый результат отсутствует, смотрите дополнительные примеры выше в моем сообщении
5. @Arya.. Я также добавил решение на Perl .. оба результата совпадают с викториями
Ответ №2:
Вы можете использовать одну sed
команду:
sed -E 's,.*b([0-9] [[:blank:]]*ms)[[:blank:]]*/[[:blank:]]*([0-9] [[:blank:]]*ms).*,Min : 1nMax : 2,' scores.csv > new_scores.csv
Смотрите онлайн-демонстрацию sed
Сведения о шаблоне
.*b
— любые символы от 0 , как можно больше, вплоть до границы слова, за которой следуют последующие шаблоны([0-9] [[:blank:]]*ms)
— Группа 1: 1 или более цифр, 0 пробелы,ms
подстрока[[:blank:]]*/[[:blank:]]*
— a/
заключенный в 0 или более пробелов([0-9] [[:blank:]]*ms)
— Группа 2: 1 или более цифр, 0 пробелов,ms
подстрока.*
— остальная часть строки.
Шаблон замены — это Min : 1nMax : 2
, где 1
относится к тексту, записанному с помощью группы 1, и 2
относится к тексту, записанному с помощью группы 2.
Ответ №3:
Не могли бы вы, пожалуйста, попробовать следующее. Просто установите правильные FS
(разделители полей) для каждой строки и затем распечатайте их (БЕЗ манипуляций с данными и т.д.)
awk -F"Inference Time : |/| ms" -v OFS=" : " 'FNR==1{$1=$1;print $1,$3 ORS $2,$5}' Input_file
Объяснение: Теперь добавляю объяснение для приведенного выше кода.
awk -F"Inference Time : |/| ms" -v OFS=" : " ' ##Setting field separator as string Inference Time : OR / OR ms for all lines and setting OFS as space colon space here.
FNR==1{ ##Checking condition if line is 1st line then do following.
$1=$1 ##Re-setting $1=$1 to reflect value of OFS here.
print $1,$3 ORS $2,$5 ##Printing values of $1,$3 then ORS with $2,$5 here as per OP ask.
} ##Closing BLOCK for FNR==1 condition here.
' Input_file ##Mentioning Input_file name here.
Вывод будет следующим.
Min : 70
Max : 290
Комментарии:
1. @Arya, не могли бы вы, пожалуйста, проверить этот ответ и дать мне знать, если это поможет, добавил правильное объяснение и здесь.
Ответ №4:
первое, что вы могли бы разделить пробелом и косой чертой. И посмотрите на каждый элемент:
awk -F'[/ ]' '{ for (i = 1; i <= NF; i) print i ": " $i}' scores.csv
1: Min
2: Max
3: Inference
4: Time
5: :
6: 70
7: ms
8:
9:
10: 290
11: ms
после этого вы берете нужные элементы:
awk -F'[/ ]' '{ print "Min : " $6; print "Max : " $10 }' scores.csv
Min : 70
Max : 290