Многострочное регулярное выражение должно совпадать в файле несколько раз (однострочная команда, если это возможно) - PullRequest
0 голосов
/ 13 декабря 2018

Я пытаюсь преобразовать некоторую (многострочную) информацию об истории git (извлечь изменения имени файла) в файл CSV.Вот мое регулярное выражение и пример файла .Он отлично работает на этом сайте.

Regex:

commit (.+)\n(?:.*\n)+?similarity index (\d+)+%\n(rename|copy) from (.+)\n\3 to (.+)\n

Пример ввода:

commit 2701af4b3b66340644b01835a03bcc760e1606f8
Author: ostrovsky.alex <ostrovsky.alex@a51b5712-02d0-11de-9992-cbdf800730d7>
Date:   Sat Oct 16 20:44:32 2010 +0000

    * Moved old sources to Maven src/main/java

diff --git a/alexo-chess/src/ao/chess/v2/move/Pawns.java b/alexo-chess/src/main/java/ao/chess/v2/move/Pawns.java
similarity index 100%
rename from alexo-chess/src/ao/chess/v2/move/Pawns.java
rename to alexo-chess/src/main/java/ao/chess/v2/move/Pawns.java

commit ea53898dcc969286078700f42ca5be36789e7ea7
Author: ostrovsky.alex <ostrovsky.alex@a51b5712-02d0-11de-9992-cbdf800730d7>
Date:   Sat Oct 17 03:30:43 2009 +0000

    synch

diff --git a/src/chess/v2/move/Pawns.java b/alexo-chess/src/ao/chess/v2/move/Pawns.java
similarity index 100%
copy from src/chess/v2/move/Pawns.java
copy to alexo-chess/src/ao/chess/v2/move/Pawns.java

commit b869f395429a2c1345ce100953bfc6038d9835f5
Author: ostrovsky.alex <ostrovsky.alex@a51b5712-02d0-11de-9992-cbdf800730d7>
Date:   Wed Oct 7 22:43:06 2009 +0000

    MctsPlayer works

diff --git a/ao/chess/v2/move/Pawns.java b/src/chess/v2/move/Pawns.java
similarity index 100%
copy from ao/chess/v2/move/Pawns.java
copy to src/chess/v2/move/Pawns.java

commit 4c697c510f5154d20be7500be1cbdecbaf99495c
Author: ostrovsky.alex <ostrovsky.alex@a51b5712-02d0-11de-9992-cbdf800730d7>
Date:   Wed Sep 23 15:06:17 2009 +0000

    * synch

diff --git a/v2/move/Pawns.java b/ao/chess/v2/move/Pawns.java
similarity index 95%
rename from v2/move/Pawns.java
rename to ao/chess/v2/move/Pawns.java
index e0172a3..e3659c5 100644
--- a/v2/move/Pawns.java
+++ b/ao/chess/v2/move/Pawns.java

Однако, когда я пытаюсь запустить следующую команду perl (в git bash на Windows 10) я получаю только одну совпадающую строку (в отличие от 4 строк в примере, которые вы можете увидеть на сайте, на который я ссылался выше).

Я знаю, что это, вероятно, что-то глупое, как будто это должно быть в цикле.Но я запутался в том, что хлюпал -0777 и применял шаблон несколько раз.Я попробовал опцию -p, но она распечатывает весь ввод, и я хочу видеть только вывод из print (то есть, строки CSV).Я также думал, что /g заставит шаблон быть примененным несколько раз к входному файлу, но поскольку -0777 делает все это одной строкой, я больше не уверен.

<Pawns.java.history.txt perl -0777 -ne 'if (/commit (.+)\n(?:.*\n)+?similarity index (\d+)+%\n(rename|copy) from (.+)\n\3 to (.+)\n/g) { print $1.",".$2.",".$3.",".$4.",".$5."\n" }'

Вывод толькоодна строка, тогда как в общем случае файл примера *1023* должен содержать 4 строки *:

2701af4b3b66340644b01835a03bcc760e1606f8,100,rename,alexo-chess/src/ao/chess/v2/move/Pawns.java,alexo-chess/src/main/java/ao/chess/v2/move/Pawns.java

Ожидаемый результат:

2701af4b3b66340644b01835a03bcc760e1606f8,100,rename,alexo-chess/src/ao/chess/v2/move/Pawns.java,alexo-chess/src/main/java/ao/chess/v2/move/Pawns.java
ea53898dcc969286078700f42ca5be36789e7ea7,100,copy,src/chess/v2/move/Pawns.java,alexo-chess/src/ao/chess/v2/move/Pawns.java
b869f395429a2c1345ce100953bfc6038d9835f5,100,copy,ao/chess/v2/move/Pawns.java,src/chess/v2/move/Pawns.java
4c697c510f5154d20be7500be1cbdecbaf99495c,95,rename,v2/move/Pawns.java,ao/chess/v2/move/Pawns.java

Ответы [ 2 ]

0 голосов
/ 13 декабря 2018

Вам просто нужно конвертировать if с while:

perl -0777 -ne 'while (/commit (.+)\n(?:.*\n)+?similarity index (\d+)+%\n(rename|copy) from (.+)\n\3 to (.+)\n/g) { print $1.",".$2.",".$3.",".$4.",".$5."\n" }' file

2701af4b3b66340644b01835a03bcc760e1606f8,100,rename,alexo-chess/src/ao/chess/v2/move/Pawns.java,alexo-chess/src/main/java/ao/chess/v2/move/Pawns.java
ea53898dcc969286078700f42ca5be36789e7ea7,100,copy,src/chess/v2/move/Pawns.java,alexo-chess/src/ao/chess/v2/move/Pawns.java
b869f395429a2c1345ce100953bfc6038d9835f5,100,copy,ao/chess/v2/move/Pawns.java,src/chess/v2/move/Pawns.java
4c697c510f5154d20be7500be1cbdecbaf99495c,95,rename,v2/move/Pawns.java,ao/chess/v2/move/Pawns.java
0 голосов
/ 13 декабря 2018

Оператор //g возвращает захваченные результаты в контексте списка.Поскольку существует 5 наборов захватывающих скобок и 4 совпадения, возвращаемый список содержит 20 элементов.Вам нужно перебрать этот список.Ваш код смотрит только на первое совпадение.Вот одна из техник:

perl -0777 -nE '
    @matches = /commit (.+)\n(?:.*\n)+?similarity index (\d+)+%\n(rename|copy) from (.+)\n\3 to (.+)\n/g;
    $" = ",";
    while (@matches) {
        @thismatch = splice @matches, 0, 5;
        say "@thismatch";
    }
' Pawns.java.history.txt 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...