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

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

(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 

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 } 
  • По какому случаю будет изменен индекс inode?
  • Нужно преобразовать столбец timestamp unix epoch в каждую строку с помощью sed или awk
  • Как отсортировать файлы в Bash с помощью ddmmyy timestamps в имени
  • Загрузите только недавно измененные файлы с помощью wget over FTP
  • Когда был открыт последний файл?
  • Извлеките метки времени и найдите разницу
  • ls показывает временную метку без времени для файла на NFS
  • Можно ли использовать команду at для планирования задания, которое должно выполняться с заданной меткой времени?
  • эпоха для GMT
  • Solaris + отметка времени файла отображения
  • Копирование новейших файлов
  • Как найти дату создания файла?
  • Interesting Posts

    Команда, чтобы знать привилегии группы пользователей

    Узнайте название интерфейса Linux

    Удалить форматирование терминала из файла

    fstrim выравнивает более половины размера раздела, даже если раздел монтируется с отбрасыванием

    Изменение шаблонов гвоздики zsh для использования с cp

    найти псевдоним с поиском

    Что делает dd, когда недостаточно свободного места

    Команда дерева для множественного включения и исключает

    Как накапливать некоторые значения в столбце на основе информации в другом столбце из того же файла данных?

    Цвета в Man Pages

    Какая область интерфейса (глобальная или ссылка) используется?

    Запомните пароль для ключа ssh в течение некоторого времени

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

    Виртуальная бокс-машина, Созданная в Windows, работает на Linux?

    Я не могу включить пространство подкачки на CentOS 7

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