Заменить символ алфавитом в зависимости от позиции в строке

У меня есть такой вывод:

(2+05:10) (10:19) (00:45) 

Этот выход представляет собой часы дня и минуты. Я хотел бы заменить ':' на 'd', 'h' и 'm' соответственно, чтобы получить это

 2d05h10m 10h19m 00h45m 

В настоящее время я пытался,

  sed -e 's/(//g; s/)//g; s/+/:/g'|awk '{split($0,s,":"); print s[1]"d" s[2]"h"s[3]"m"}') 

который дает (и вот я испортил!)

 6d05h20m 3d15h17m 1d02h27m 00d08hm 00d11hm 02d25hm 02d30hm 16d50hm 5d00h39m 21d48hm 

  • Временная отметка файла на установленном диске показывает 1 час отставания
  • Как я могу увидеть историческое время изменения файла?
  • Удалить файлы из списка, которые были созданы / изменены в субботу
  • Список файлов с момента времени X до времени Y
  • Время изменения Solaris 10
  • touch и tar из текстового файла
  • Каков наиболее эффективный способ добавления миллисекунд к этому коду?
  • Использует ли `git archive` неправильную временную метку файла?
  • 3 Solutions collect form web for “Заменить символ алфавитом в зависимости от позиции в строке”

    Звучит как

     < file tr '+:)' dhm | tr -d '(' 

    Сделал бы это. Или для более точного совпадения с этим шаблоном:

     sed 's/(\([0-9]\{1,\}\)+\([0-9]\{1,\}\):\([0-9]\{1,\}\))/\1d\2h\3m/g s/(\([0-9]\{1,\}\):\([0-9]\{1,\}\))/\1h\2m/g' < file 

    Который с некоторыми реализациями sed вы можете упростить использование расширенных регулярных выражений, чтобы:

     sed -E 's/\(([0-9]+)\+([0-9]+):([0-9]+)\)/\1d\2h\3m/g s/\(([0-9]+):([0-9]+)\)/\1h\2m/g' < file 

    Или с одной командой s с perl :

     perl -pe 's{\((?:(\d+)\+)?(\d+):(\d+)\)}{ ($1 && "$1d") . "$2h$3m"}ge' < file 

    Или:

     perl -pe 's/\((\d*\+?\d+:\d+\))/$1 =~ y|+:)|dhm|r/ge' < file 

    Вам не хватает awk решения. Вот тот, который опускает нулевые элементы:

    parse.awk

     # Start with empty variables { d = h = m="" } # Determine format and set variables accordingly. # Force numeric interpretation by multiplying by one NF==5 { d = $2*1; h = $3*1; m = $4*1 } NF==4 { d = "" ; h = $2*1; m = $3*1 } # Only set value if the number is greater than zero { d = d > 0 ? d "d" : "" h = h > 0 ? h "h" : "" m = m > 0 ? m "m" : "" } length(dhm) > 1 { print dhm } length(dhm) == 0 { print "Now" } 

    Выполните его следующим образом:

     awk -f parse.awk -v FS='[()+:]' file 

    Вывод:

     2d5h10m 10h19m 45m 

    Простой (но слегка неэффективный) скрипт perl должен быть достаточным

     cat output_file | perl simple.pl 

    simple.pl

     @seps=split /:/,"d:h:m"; while(<>) { chomp ; $_=~s/[\(\)]//g; #remove braces @x = split /:/, $_; #get parts $s=""; for($i=$#x,$j=$#sep;$i>=0; $i--,$j--) { #iterate on parts and corresponding separator $s=$x[$i].$seps[$j].$s; #create print string } print "$s\n"; #print this line } 
    Interesting Posts

    Как настроить скрипт для запуска с правами неинтерактивно?

    Настройка маршрутизатора для доступа к компьютеру через внешний IP-адрес

    Как заставить команду diff игнорировать некоторые строки второго файла (bash)?

    Странная регистрация ошибок в BBB

    В чем разница между обновлением программного обеспечения и обновлением?

    Есть ли способ перестроить только часть диска в настройке mdraid5?

    Как изменить карту сменных клавиш в tmux?

    Что такое «s» внутри «$ -»?

    Как фильтровать все файлы типа, содержащие шаблон

    Помощь с повторением поля A в CSV-файле, где поле B имеет указанное значение

    Удалите программное обеспечение python должным образом

    Необходимо написать сценарий «thirsty.sh»: BASH

    Несколько профилей firefox

    Как перенести виртуальную машину IDE в виртуальную виртуальную машину?

    Значение пересечения границ файловой системы, – однофайловая система и т. Д.

    Linux и Unix - лучшая ОС в мире.