Заменяйте символы по определенному индексу, отсчитываемому сзади

Я хочу изменить некоторые символы в строке, которую я создаю. Я делаю файлообмен и из каждого файла мне нужно добавить информацию о «stat». Например, имя файла "K181_111126.CATProduct" приводит к "K181_111126.CATProduct.2011-11-28 13:33:33.722342000 +0100" . Последние 16 символов, которые мне не нужны, я решил:

 find . -type f -exec stat -c%n.%y {} \; | sed 's/.\{16\}$//' 

Результат: "K181_111126.CATProduct.2011-11-28 13:33:33" Моя проблема в том, что мне нужно изменить пространство (9-й символ сзади) между датой и временем с помощью «-» и всех «:» в время (13:33:33) с точкой "."
Строки имеют разную длину, так что я могу рассчитывать только сзади. Может кто-нибудь мне помочь?

  • sed: вставьте sth перед последующими строками, которые начинаются одинаково, но не совпадают
  • Как извлечь несколько строк, разделенных запятой из файла журнала?
  • Цвет полосы в OS X с BSD sed (или любым другим инструментом)
  • Sed - Заменить первые k экземпляров слова в файле
  • Сравните два столбца файла
  • Как удалить строки, содержащие IP-адрес?
  • И операция по 2 столбцам (даты доступа и mofidy) в файле в linux
  • bash найти строки, начинающиеся со строки
  • Извлечение загрузки из вывода свернуть
  • Как удалить определенный номер в файле?
  • почему этот простой скрипт sed не работал »nginx -V 2> & 1 | sed -r 's / - / \\ n / g' "
  • Как найти слово в файле и вставить текст на две строки ниже?
  • 3 Solutions collect form web for “Заменяйте символы по определенному индексу, отсчитываемому сзади”

    Заменяйте пространство и двоеточия одновременно с помощью немного более длинного регулярного выражения.

     find . -type f -exec stat -c%n.%y {} \; | sed 's/ \(..\):\(..\):\(..\).\{16\}$/-\1.\2.\3/' 

    Пробел до 24-го символа с конца сопоставляется, затем мы сопоставляем и фиксируем следующие 2 символа, запятую, следующие 2, комру и другую 2; то последние 16 сопоставляются и заменяются ничем. Первое захваченное выражение можно вызвать с помощью обратной ссылки \1 (вторая с \2 и т. Д.). Другими словами, две цифры после пробела «заменяются» собой, то есть эффективно сохраняются, а затем точка, следующие две и т. Д.

    Я думаю, что это то, что вы ищете:

     $ s='K181_111126.CATProduct.2011-11-28 13:33:33.722342000 +0100' $ echo "$s" | rev | sed -E 's/.{16}//; s/:/./; s/:/./; s/ /-/' | rev K181_111126.CATProduct.2011-11-28-13.33.33 

    Это использует rev для обратного ввода символа строки, так что его легче обрабатывать и, наконец, rev снова

    • s/.{16}// удалить первые 16 символов
    • s/:/./; s/:/./ s/:/./; s/:/./ изменить первые два : к .
    • s/ /-/ изменить первое пространство на -
     find ... | sed -Ee ' s/.{16}$// :a;s/:([^:[:blank:]]*)$/.\1/;ta s/[[:blank:]]([^[:blank:]]+)$/-\1/ ' 

    Где после удаления оставшихся 16 символов так же, как и вы, мы настраиваем цикл для постепенного преобразования : -> . и когда это будет сделано, измените последний самый пустой символ на тире. Это необходимо, так как имя файла также может содержать пустые символы, и мы должны игнорировать их.

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