2015-04-27 2 views
4

Мне нужно что-то заменить в нескольких файлах с помощью regex. Я делаю это вот так:Подсчитайте количество заметок, сделанных с помощью regex

#!/usr/bin/env bash 

find /path/to/dir \ 
    -type f \ 
    -name '*.txt' \ 
    -exec perl -e 's/replaceWhat/replaceWith/ig' -pi '{}' \; \ 
    -print \ 
    | awk '{count = count+1 }; END { print count " file(s) handled" }' 

echo "Done!" 

Этот код показывает пользователю количество файлов, в которые он имел дело. Но как я могу считать не файлы, а заменять? Каждый обработанный файл может генерировать нуль, один или несколько замещений с регулярным выражением.

+1

Если вы решите написать весь свой код в Perl, вы можете использовать синтаксис '(?? {code})' для увеличения счетчика в замене. см. http://perldoc.perl.org/perlre.html –

ответ

1

Вы можете добавить дополнительный -exec вызов grep, а затем передать количество матчей awk, а не только имя файла:

#!/usr/bin/env bash 

find /path/to/dir \ 
    -type f \ 
    -name '*.txt' \ 
    -exec grep -c 'replaceWhat' '{}' \; \ 
    -exec perl -e 's/replaceWhat/replaceWith/ig' -pi '{}' \; \ 
    | awk '{count += $0 }; END { print count " replacement(s) made" }' 

echo "Done!" 

Пример (замена «перед» с «после»):

$ tail -n +1 *.txt 
==> 1.txt <== 
before 
foo 
bar 

==> 2.txt <== 
foo 
bar 
baz 

==> 3.txt <== 
before 
foo 
before 
bar 
before 

$ ./count_replacements.sh 
4 replacement(s) handled 
$ tail -n +1 *.txt 
==> 1.txt <== 
after 
foo 
bar 

==> 2.txt <== 
foo 
bar 
baz 

==> 3.txt <== 
after 
foo 
after 
bar 
after