Добавление символа в n-ю позицию совпадающей строки

Я выяснил, обнаружив в этом потоке , что strace может вызывать только исполняемый файл.

Сработало изменение моего примера, приведенного выше.

util.sh

#!/bin/bash
echo "Earth, Wind, Fire and Water"

strace_sample.sh

#!/bin/bash

function funk_b {
  echo "Get on up"
  #strace -o funk_a.out -c -Ttt funk_a
  strace -o util.out -c -Ttt ./util.sh
}

Результат

$ funk_b
Get on up
Earth, Wind, Fire and Water
$ more util.out 
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
  0.00    0.000000           0         7           read
  0.00    0.000000           0         1           write
  0.00    0.000000           0        27        18 open
:

1
25.07.2016, 19:15
3 ответа

Вы можете использовать perl

perl -lane 'map{length==10&&/^541/&&s/.{4}/$&9/}@F;print join(" ",@F)' file

Использовать карту для выполнения проверок и подпрограмм для каждого поля. Затем печатает массив полей, соединенных с помощью одиночный пробел (так что форматирование испортится, если отдельные пробелы между полями не будут согласованы)

или просто с использованием регулярного выражения

perl -lane 'map{s/^541.\K.{6}$/9$&/}@F;print join(" ",@F)' file

Вывод:

54149444444 87654873234 88888888888
6646666666 54122222222
54155555558888 54176543235 54169666666
1
27.01.2020, 23:19

Переносимость:

sed '
  s/.*/ & /; # add a leading and trailing space
  :1
    s/\([[:blank:]]541[^[:blank:]]\{2\}\)\([^[:blank:]]\{5\}[[:blank:]]\)/\19\2/g
    # replace in a loop until there is no more match
  t1
  # remove the blanks we added earlier:
  s/^ //;s/ $//'

Вы можете избежать временного добавления начальных и конечных пробелов, ища появление этих 10 непустых строк в начале или конец списка в дополнение к следующему / предшествующему пробелу. Это можно сделать с помощью одного регулярного выражения POSIX, но это немного громоздко:

sed '
  :1
    s/^\(\(.*[[:blank:]]\)\{0,1\}541[^[:blank:]]\{2\}\)\([^[:blank:]]\{5\}\([[:blank:]].*\)\{0,1\}\)$/\19\3/
  t1'

С perl , используя операторы просмотра:

perl -lpe 's/((?<!\H)541\H\H)(\H{5})(?!\H)/${1}9$2/g'

Или обрабатывая слова по одному:

perl -lpe 's{\H+}{$&=~s/^541..\K.{5}$/9$&/r}ge'

( \ K и флаг подстановки r требуют относительно недавней версии perl ).

1
27.01.2020, 23:19

Как видно из примера OP означает слово , а не строку , поэтому

sed 's/\b541./&9/g' file

Если 541 может начинаться с любого места в слове (не с начала )

sed 's/\b\S*541/\n&/g     #mark a beginning of word(s) with pattern
     s/\n\(....\)/\19/g   #remove mark and do adding
    ' file

Вы можете ограничить количество символов в словах следующим образом

sed 's/\b\(541.\)\(\S\{6\}\)\b/\19\2/g' file

или в более общем виде

sed 's/\b541./&\n/g;s/\n\S\{6\}\b/9&/g;s/\n//g' file
2
27.01.2020, 23:19

Теги

Похожие вопросы