linee grep dopo la partita fino alla fine


12

Ho seguito l'output di git status, come faccio grepper tutto dopo 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]$ 

In questo modo, ma senza specificare il numero di righe, come il -Aparametro in 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]$ 

C'è un modo per farlo?

[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]$ 

Perché non puoi usare -Aun numero abbastanza grande come argomento?
Kasperd,

Risposte:


17

Con GNU grep(testato con la versione 2.6.3):

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

Utilizza -Pper le espressioni regolari perl, -zper abbinare anche la nuova riga \ne -oper stampare solo ciò che corrisponde al modello.

Il regex ha spiegato :

Innanzitutto abbiniamo qualsiasi carattere ( .) zero o più volte ( *) fino a quando si verifica una ricorrenza della stringa Untracked files. Ora, la parte all'interno delle parentesi (.*\n)corrisponde a qualsiasi carattere tranne uno newline ( .) zero o più volte ( *) seguito da una newline ( \n). E tutto ciò (che si trova all'interno dei backets) può avvenire zero o più volte; questo è il significato dell'ultimo *. Ora dovrebbe corrispondere a tutte le altre righe, dopo la prima occorrenza di Untracked files.


3
Una risposta che effettivamente utilizza grep, sono impressionato!
Hyppy,

@hyppy me too) e poi di nuovo, il match si è evoluto anche in Perl regex)
alexus

1
Questo non funziona bene se l'input ha molte righe. L'ho provato su Ubuntu 14.04 e se la corrispondenza è più lunga di circa 8000 linee, segfault.
Kasperd,

2
@kasperd Penso che con oltre 8000 righe, grepnon sia lo strumento giusto. Ma per il resto questa domanda è (penso) per l'utente di vedere solo l'output pertinente, quello che ovviamente non hai a 8000+ righe, grepedite o meno.
caos,

1
@chaos Ho anche provato grep -A999999999 'Untracked files'con 1000000 linee prima della partita e 1000000 linee dopo la partita. Questo approccio ha funzionato bene. Quindi greppuoi farlo. Il problema con il tuo approccio è che lo stai forzando a eseguire una singola corrispondenza sull'intero file anziché su singole righe.
Kasperd,

13

Se non ti dispiace usare sed, ecco una possibile soluzione

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

Questo ha il vantaggio di funzionare con un semplice grep e sed di UNIX, mentre la soluzione accettata richiede GNU grep.
Guntram Blohm sostiene Monica

3

Vorrei usare awkper questo:

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

Questa /Untracked files/,0è un'escrezione di portata. Valuta True per la prima volta Untracked filese fino 0a True. Dal momento che ciò non accade mai, stampa il resto del file.

Si noti che awkil comportamento di un True è quello di stampare il record corrente (linea, normalmente), ecco perché non è necessario chiamare esplicitamente print.


2

Puoi provare:

git status | grep -A99 Untracked

dove -Astampare le righe del contesto finale dopo la partita.

In alternativa, utilizzare moreo less, ad esempio:

git status | less +/Untracked

Per scopi di scripting, userei ex/ vi:

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

Per includere la riga con i file non tracciati , utilizzare kd1Ginvece di d1G.

O senza tubazioni e /dev/stdin, la sintassi sarebbe: ex ... <(git status).


Ho incluso -Anella mia domanda originale, ma mi piace more +/Untrackedparte della tua risposta.
alexus,

@alexus Se stai scrivendo uno script, ho aggiunto la versione con excui è equivalente vi -e.
Kenorb,

grazie, credo more/ lessè molto utile)
alexus

1

Per un one-liner con parentesi di generare una subshell in modo da evitare di conservare le variabili:

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

Puoi semplicemente dirottare alla fine di tutto ciò che devi fare con esso.

Oppure puoi usarlo in qualunque script di shell

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

Sostituisci echo "$LINE"con qualunque cosa tu voglia fare con i dati. Se si desidera saltare la riga "File non monitorati", è sufficiente cambiare i due test.


0

puoi usare qualcosa del genere, ho usato Perl, il seguente comando impostato count = 1se abbino una stringa nella riga corrente e quando il ciclo while è finito controllo le variabili di conteggio e stampo l'intervallo di righe da cui avviene la corrispondenza all'ultima linea

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
Troppo complicato. Una semplice soluzione Perl è qui: stackoverflow.com/a/18167194/111036 . Una variante che include la linea da abbinare potrebbe essere:perl -ne 'print if /Untracked files:/ .. 0'
mivk
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.