греп лінії після матчу до кінця


12

У мене є наступний висновок від git status, як мені робити grepвсе після Untracked files:

[alexus@wcmisdlin02 Test]$ git status 
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#   new file:   app/.gitignore
#   new file:   app/app.iml
#   new file:   app/build.gradle
#   new file:   app/proguard-rules.pro
#   new file:   app/src/androidTest/java/org/alexus/test/ApplicationTest.java
#   new file:   app/src/main/AndroidManifest.xml
#   new file:   app/src/main/java/org/alexus/test/MainActivity.java
#   new file:   app/src/main/res/layout/activity_main.xml
#   new file:   app/src/main/res/menu/menu_main.xml
#   new file:   app/src/main/res/mipmap-hdpi/ic_launcher.png
#   new file:   app/src/main/res/mipmap-mdpi/ic_launcher.png
#   new file:   app/src/main/res/mipmap-xhdpi/ic_launcher.png
#   new file:   app/src/main/res/mipmap-xxhdpi/ic_launcher.png
#   new file:   app/src/main/res/values-w820dp/dimens.xml
#   new file:   app/src/main/res/values/dimens.xml
#   new file:   app/src/main/res/values/strings.xml
#   new file:   app/src/main/res/values/styles.xml
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#   .gitignore
#   .idea/
#   Test.iml
#   build.gradle
#   gradle.properties
#   gradle/
#   gradlew
#   gradlew.bat
#   settings.gradle
[alexus@wcmisdlin02 Test]$ 

Як це, але не вказуючи кількість рядків, як -Aпараметр у GNU grep:

[alexus@wcmisdlin02 Test]$ git status | grep -A100 'Untracked files'
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#   .gitignore
#   .idea/
#   Test.iml
#   build.gradle
#   gradle.properties
#   gradle/
#   gradlew
#   gradlew.bat
#   settings.gradle
[alexus@wcmisdlin02 Test]$ 

Чи є спосіб це зробити?

[alexus@wcmisdlin02 Test]$ grep --version
grep (GNU grep) 2.20
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Mike Haertel and others, see <http://git.sv.gnu.org/cgit/grep.git/tree/AUTHORS>.
[alexus@wcmisdlin02 Test]$ 

Чому ви не можете використовувати -Aаргумент із достатньою кількістю?
kasperd

Відповіді:


17

З GNU grep(протестовано у версії 2.6.3):

git status | grep -Pzo '.*Untracked files(.*\n)*'

Використовує -Pдля регулярних виразів perl, -zщоб також збігати новий рядок \nі -oдрукувати лише те, що відповідає шаблону.

Регекс пояснив :

Спочатку ми узгоджуємо будь-який символ ( .) нуль або кілька разів ( *) до появи рядка Untracked files. Тепер частина всередині дужок (.*\n)відповідає будь-якому символу, окрім нового рядка ( .) нуля або декількох разів ( *), а за ним нового рядка ( \n). І все це (це всередині бекасів) може статися нульовим або багаторазовим; ось сенс останнього *. Тепер він повинен відповідати всім іншим рядкам після першого виникнення Untracked files.


3
Відповідь, яка насправді використовує grep, я вражений!
Хіпі

@ привіт мене теж), а потім знову збіг розвинувся
Perge

1
Це не працює добре, якщо на вході багато рядків. Я тестував його на Ubuntu 14.04, і якщо збіг довший приблизно 8000 рядків, він починає змінюватись.
kasperd

2
@kasperd Я думаю, що з 8000+ рядків grepце не правильний інструмент. Але в іншому випадку це питання (я думаю) для користувача бачити лише відповідний вихід, чого у вас, очевидно, немає у 8000+ рядків, grepредагувати чи ні.
хаос

1
@chaos Я також перевірив grep -A999999999 'Untracked files'1000000 рядків перед матчем та 1000000 рядків після матчу. Такий підхід спрацював чудово. Так grepможе це зробити. Проблема вашого підходу полягає в тому, що ви змушуєте його виконувати єдину відповідність у всьому файлі, а не на окремих рядках.
kasperd

13

Якщо ви не проти використовувати sed, ось можливе рішення

git status | sed -n -e '/Untracked files/,$p'

Це має перевагу в тому, що він працює з звичайним UNIX grep і sed, тоді як прийняте рішення вимагає GNU grep.
Гунтрам Блом підтримує Моніку

3

Я б використовував awkдля цього:

git status | awk '/Untracked files/,0'

Це /Untracked files/,0експресія на дальність. Вона оцінюється в True з першого разу Untracked filesі поки не 0оцінюється в True. Оскільки цього ніколи не відбувається, він друкує решту файлу.

Зауважте, що awkповедінка до True - це друк поточного запису (як правило, рядок), тому нам не потрібно явно дзвонити print.


2

Ви можете спробувати:

git status | grep -A99 Untracked

де -Aбудуть надруковані рядки проміжного контексту після матчу.

Альтернативно використовувати moreабо less, наприклад:

git status | less +/Untracked

Для цілей сценарію я б використовував ex/ vi:

git status | ex -s +"/Untracked/norm d1G" +%p -cq! /dev/stdin

Щоб включити рядок з файлами без відстеження , використовуйте kd1Gзамість d1G.

Або без трубопроводу і /dev/stdinсинтаксис буде виглядати так : ex ... <(git status).


Я включив -Aу своє первісне запитання, але мені подобається more +/Untrackedчастина вашої відповіді.
alexus

@alexus Якщо ви пишете сценарій, я додав версію, exяка еквівалентна vi -e.
kenorb

дякую, я вважаю more/ lessдуже корисно)
alexus

1

Щоб однорозмір з дужками породжував підшару, щоб уникнути збереження змінних:

(while read LINE ; do [[ "$LINE" =~ "Untracked files" ]] && MATCHED=1 ; \
   [[ "$MATCHED" = 1 ]] && echo "$LINE" ; done < <(git status))

Ви можете просто вставити в кінці цього все, що ще вам потрібно зробити.

Або ви можете використовувати його в будь-якому сценарії оболонки

while read LINE ; do
    [[ "$LINE" =~ "Untracked files" ]] && MATCHED=1
    [[ "$MATCHED" = 1 ]] && echo "$LINE"
done < <(git status)

Замініть на echo "$LINE"те, що ви хочете зробити з даними. Якщо ви хочете пропустити рядок "Неназвані файли", тоді просто переключіть два тести.


0

ви можете використовувати щось подібне, я використав Perl, наступний набір команд, count = 1якщо я збігаюсь з рядом у поточному рядку, і коли цикл while закінчений, я перевіряю кількість змінних і друкую діапазон рядків, звідки відбувається відповідність останнім рядок

ls -al | perl -e '@LINES = (); $n = 0 ; $nline = 0; while(<>){ push(@LINES, $_); $n++; if($_ =~ m/mirror/i) { $count = 1; $nline = $. - 1 };};  if($count != 0){ foreach $i($nline..$n-1){ print "\t$LINES[$i]\n";}}'

1
Набагато складне. Тут просте рішення Perl: stackoverflow.com/a/18167194/111036 . Варіація, що включає лінію для відповідності, може бути:perl -ne 'print if /Untracked files:/ .. 0'
mivk
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.