ansible_all_ipv4_addresses
уже является массивом, поэтому вам не нужно split
его:
- copy:
dest: /tmp/ips
content: "{{ ansible_all_ipv4_addresses | join('\n') }}"
Это даст желаемый результат.
Вы можете использовать pcregrep
режим нескольких линий -:
$ pcregrep --include='\.h$' -rM '(?s)^\s*(\w+\s+)*int cacheflush\s*\(.*?;' glibc
glibc/sysdeps/unix/sysv/linux/mips/sys/cachectl.h:extern int cacheflush (void *__addr, const int __nbytes, const int __op) __THROW;
glibc/sysdeps/unix/sysv/linux/csky/sys/cachectl.h:extern int cacheflush (void *__addr, const int __nbytes,
const int __op) __THROW;
glibc/sysdeps/unix/sysv/linux/nios2/sys/cachectl.h:extern int cacheflush (void *__addr, const int __nbytes, const int __op) __THROW;
А с помощью PCRE вы получаете доступ к большинству расширенных операторов регулярных выражений Perl. Здесь мы используем:
\w
и \s
для слов и пробелов. (?s)
:позволяет флагу s
для .
также совпадать с символами новой строки. *?
:не -жадная версия *
. Таким образом, он соответствует первому вхождению ;
, а не последнему, как в жадной версии. Для получения подробной информации см. справочную страницу pcrepattern(3)
.
Я придумал (уродливое )решение:
Считайте с /begin/
по/^$/
(пустую строку ), повторяя первую строку шаблона, чтобыsed(1)
мог воздействовать на нее на последующем шаге.
Используйте sed(1)
, чтобы найти от /begin/
до /end/
. Оставьте пустые строки на этом шаге, чтобы иметь возможность использоватьuniq(1)
для правильного удаления на следующем шаге строк, которые мы повторили на шаге 1.
Используйтеuniq(1)
для удаления повторяющихся строк.
$ syscall=cacheflush;
$ return=int;
$ pattern="^[a-z ]*${return} ${syscall}[ ]*(";
$ find glibc/ -name '*.h' \
|xargs sed -n -e "/${pattern}/p" -e "/${pattern}/,/^$/p" \
|sed -n -e "/${pattern}/,/;/p" -e '/^$/p' \
|uniq;
extern int cacheflush (void *__addr, int __nbytes, int __op) __THROW;
extern int cacheflush (void *__addr, const int __nbytes,
const int __op) __THROW;
extern int cacheflush (void *__addr, const int __nbytes, const int __op) __THROW;
extern int cacheflush (void *__addr, const int __nbytes, const int __op) __THROW;
Пожалуйста, предложите более простое решение:)
Нет необходимости вызывать sed
дважды, вы просто проверяете перед вводом диапазона, находятся ли начало/конец в одной строке.
$ find glibc/ -name '*.h' \
|xargs sed \
-e "/${pattern}.*;\$/b" \
-e "/${pattern}/,/;\$/p" \
-e 'd' ;
Обратите внимание, что будет хорошо, если вы ограничите утилиту find
поиском только обычных файлов, в противном случае вы можете увидеть предупреждения, когда sed
работает с каталогом, имя которого заканчивается на.h