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

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

(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 

  • эпоха для GMT
  • Получение файлов для текущей даты в Linux?
  • Unix-эпоха в миллисекундах
  • Найти файлы между двумя папками в linux?
  • Что вы можете сделать с файлом без запуска отметки «Изменить»?
  • Как определить точное время, когда файл был создан и / или изменен?
  • Почему у моего файла есть несколько записей crtime?
  • Как извлечь длинное поле для листинга?
  • 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

    передача файла в настройках монтирования

    Debian не сохраняет предпочтения пользователя какой-либо программы

    Песочница учетная запись и предотвратить ее от любых изменений системы

    Не удается удалить / log / var / snort как root

    Есть ли алгоритм для решения, если циклы символической ссылки?

    Как исправить ошибку make «Нет правила делать« menuconfig »цели при создании ядра для Beagleboard?

    Сопоставьте текущую строку до строки, которая не соответствует шаблону

    Скопировать изображение из буфера обмена в файл

    Сплошное поведение сравнения со стороны Solaris

    Являются ли файлы устройств реализованы драйверами устройств или ядрами ОС?

    Выполнять параллельные параллельные параллели

    Избегайте переформатирования списков пули с форматированием + = a

    Как загрузить tcpdumps в реальном времени на FTP?

    расширять псевдонимы перед вызовом / usr / bin / time

    Невозможно сравнить строки

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