Найти и разделить все числа в файле с помощью sed - PullRequest
2 голосов
/ 14 июня 2019

Я пытаюсь найти все числа в файле json и заменить их половинным значением исходного числа, используя sed на mac.Например, здесь я ищу 2010 и заменяю его на 1005:

file="data.json"
sed -i '' -E 's,([^0-9]|^)2010([^0-9]|$),\1 1005\2,g' "$file"

. Я хотел бы найти все экземпляры чисел и заменить их половинными значениями самих себя.Это должно было бы работать с десятичными числами, например: 2009 станет 1004,5, 10,5 станет 5,25.

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

edit: я бы хотел, чтобы он был гибким и работал со всеми формами текстовых файлов, а не только с файлами JSON.(.txt, .html, .rtf и т. д.)

Ответы [ 2 ]

3 голосов
/ 14 июня 2019

Вы можете использовать Perl с регулярным выражением с модификатором e:

perl -pe 's{(?<!\d)(\d+(?:\.\d+)?)(?!\d)}{$1/2}ge' file

Чтобы изменить встроенный файл, добавьте параметр -i:

perl -i -pe 's{(?<!\d)(\d+(?:\.\d+)?)(?!\d)}{$1/2}ge' file
perl -pi.bak -e 's{(?<!\d)(\d+(?:\.\d+)?)(?!\d)}{$1/2}ge' file # To save a backup of the original file

См. онлайн-демонстрация :

s="abc_2010_and+2009+or-10.5"
perl -pe 's{(?<!\d)(\d+(?:\.\d+)?)(?!\d)}{$1/2}ge' <<< "$s"
# => abc_1005_and+1004.5+or-5.25

Регулярное выражение (?<!\d)(\d+(?:\.\d+)?)(?!\d) соответствует

  • (?<!\d) - цифры слева не допускаются
  • (\d+(?:\.\d+)?) - группа 1 ($1): 1+ цифр, за которыми следует необязательная последовательность . и 1+ цифр
  • (?!\d) - цифра сразу справа не допускается.

RHS - $1/2 - это выражение, которое делит значение группы 1 на 2.Это достигается добавлением модификатора e в конце регулярного выражения.

0 голосов
/ 14 июня 2019

С GNU awk для мульти-символьных RS и RT это будет просто:

awk -v RS='[0-9]+([.][0-9]+)?' -v ORS= 'RT{$0=$0 RT/2} 1'

например, заимствование @Wiktors пример:

$ s="abc_2010_and+2009+or-10.5"
$ awk -v RS='[0-9]+([.][0-9]+)?' -v ORS= 'RT{$0=$0 RT/2} 1' <<< "$s"
abc_1005_and+1004.5+or-5.25

Если вы хотите перезаписать входной файл, добавьте -i inplace:

awk -i inplace -v RS...1' file
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...