Я должен найти все строки "5dp" и заменить их с" (5*0.83) разность потенциалов", округленный в меньшую сторону до целых чисел. Номер 5 мог быть любым числом, и выражение в скобках на самом деле выполняется.
Например: 31dp
должен стать 25dp
.
Я должен искать все файлы в каталоге и подкаталогах рекурсивно. Какая-либо справка?
Используя find
+ Perl:
find . -type f -exec \
perl -i -e 'use POSIX;' -pe 's/([0-9]*)dp/floor($1*.83).dp/ge' {} +
find
команда:
.
: поиски в текущей рабочей иерархии каталогов;-type f
: поиски только файлов;-exec [...] {} +
: выполняет следующую команду, подающую его результаты поиска как список аргументов;Команда Perl:
-i
: указывает что файлы, обработанные <>
конструкция должна быть отредактирована оперативная;-p
: Perl причин для принятия следующего цикла вокруг программы, которая заставляет его выполнить итерации по аргументам имени файла несколько как sed
: while (<>) {...} continue {print or die "-p destination: $!\n";}
;-e
: используемый для ввода одной строки программы; Perl не будет искать имя файла в списке аргументов;Разбивка Perl команда № 1:
use POSIX;
: импорт POSIX
модуль, необходимый для POSIX::floor
функция;Разбивка Perl команда № 2:
s
: утверждает для выполнения замены/
: останавливается команда / запускает шаблон(
: запускает группу фиксации[0-9]*
: соответствия любое количество любой цифры)
: останавливает группу фиксацииdp
: соответствия a dp
строка/
: останавливается шаблон / запускает замещающую строкуfloor($1*.83).dp
: Выражение Perl, замененное результатом floor($1*.83)
(где $1
полученная группа), сопровождаемый a dp
строка/
: останавливается замещающая строка / запускает опцииg
: утверждает для выполнения замен глобальноe
: утверждает для выполнения замещающей строки как команды PerlДемонстрационный вывод:
ubuntu@ubuntu:~/tmp$ tree
.
└── 1
├── 2
│ ├── 3
│ │ └── infile
│ └── infile
└── infile
3 directories, 3 files
ubuntu@ubuntu:~/tmp$ find . -type f -exec bash -c 'echo -e "{}:\n\n$(cat {})\n"' \;
./1/infile:
1dp 2dp 3dp 4dp 5dp
6dp 7dp 8dp 9dp 10dp
11dp 12dp 13dp 14dp 15dp
./1/2/infile:
1dp 2dp 3dp 4dp 5dp
6dp 7dp 8dp 9dp 10dp
11dp 12dp 13dp 14dp 15dp
./1/2/3/infile:
1dp 2dp 3dp 4dp 5dp
6dp 7dp 8dp 9dp 10dp
11dp 12dp 13dp 14dp 15dp
ubuntu@ubuntu:~/tmp$ find . -type f -exec perl -i -e 'use POSIX;' -pe 's/([0-9]*)dp/floor($1*.83).dp/ge' {} +
ubuntu@ubuntu:~/tmp$ find . -type f -exec bash -c 'echo -e "{}:\n\n$(cat {})\n"' \;
./1/infile:
0dp 1dp 2dp 3dp 4dp
4dp 5dp 6dp 7dp 8dp
9dp 9dp 10dp 11dp 12dp
./1/2/infile:
0dp 1dp 2dp 3dp 4dp
4dp 5dp 6dp 7dp 8dp
9dp 9dp 10dp 11dp 12dp
./1/2/3/infile:
0dp 1dp 2dp 3dp 4dp
4dp 5dp 6dp 7dp 8dp
9dp 9dp 10dp 11dp 12dp
FWIW, вот решение с остротами удара:
(Имел тот, готовый, прежде чем я считал OP, хотел, чтобы целые числа, в конце концов, таким образом использование до н.э сделали математику плавающую.)
find . -type f|while read f;do cat "$f"|while read a;do b=`echo "$a"|sed 's/.*\([0-9]\+\)dp.*/\1*0.83/'|bc`;echo "$a"|sed s/"[0-9]\+dp"/"$b"dp/;done;done
... и округленный в меньшую сторону:
find . -type f|while read f;do cat "$f"|while read a;do b=`echo "$a"|sed 's/.*\([0-9]\+\)dp.*/\1*0.83/'|bc`;b=${b%.*};echo "$a"|sed s/"[0-9]\+dp"/"$b"dp/;done;done
Намного более подробный: сценарий Python ниже:
#!/usr/bin/env python3
import os
import sys
directory = sys.argv[1]
for root, dirs, files in os.walk(directory):
for file in files:
subject = root+"/"+file
text = open(subject).read().split(" ")
for i, s in enumerate(text):
if s.endswith("dp"):
try:
n = str(int(float(s.replace("dp", ""))*0.83))+"dp"; text[i] = n
except ValueError:
pass
open(subject, "wt").write((" ").join(text))
replace_numbers.py
Выполните его командой:
python3 /path/to/replace_numbers.py <directory>
a monkey eats 234dp bananas, while 2657dp would be too much. 234 is more the 12.
становится:
a monkey eats 194dp bananas, while 2205dp would be too much. 234 is more the 12.
0.83
. Затем плавание округляется в меньшую сторону (использование int(<float>)
). Если строка, разделенная от "разности потенциалов", кажется, не только число, процесс пропускается для определенной строки (предоставление a ValueError
)