garis grep setelah pertandingan sampai akhir

12

Saya memiliki keluaran berikut dari git status, bagaimana saya grepuntuk semuanya setelah 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]$ 

Seperti ini, tetapi tanpa menentukan jumlah baris, seperti -Aparameter dalam 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]$ 

Apakah ada cara untuk melakukannya?

[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]$ 
alexus
sumber
Mengapa Anda tidak bisa menggunakan -Aangka yang cukup besar sebagai argumen?
kasperd

Jawaban:

17

Dengan GNU grep(diuji dengan versi 2.6.3):

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

Penggunaan -Puntuk perl ekspresi reguler, -zuntuk juga mencocokkan baris baru dengan \ndan -ohanya untuk mencetak yang cocok dengan pola.

Regex menjelaskan :

Pertama kita mencocokkan karakter apa pun ( .) nol atau beberapa kali ( *) hingga kemunculan string Untracked files. Sekarang, bagian dalam tanda kurung (.*\n)cocok dengan karakter apa pun kecuali baris baru ( .) nol atau beberapa kali ( *) diikuti oleh baris baru ( \n). Dan semua itu (yang ada di dalam backet) dapat terjadi nol atau beberapa kali; itulah arti yang terakhir *. Sekarang seharusnya cocok dengan semua baris lain, setelah kemunculan pertama Untracked files.

kekacauan
sumber
3
Sebuah jawaban yang benar-benar digunakan grep, saya terkesan!
Hyppy
@ hyppy saya juga) dan sekali lagi, pertandingan juga berevolusi Perl regex)
alexus
1
Ini tidak berfungsi dengan baik jika input memiliki banyak baris. Saya mengujinya di Ubuntu 14.04, dan jika pertandingan lebih panjang dari sekitar 8000 baris, itu segfaults.
kasperd
2
@kasperd Saya pikir dengan 8000+ baris, grepbukan alat yang tepat. Tetapi jika tidak, pertanyaan ini adalah (saya pikir) bagi pengguna untuk hanya melihat output yang relevan, yang jelas tidak Anda miliki di 8000+ baris, greped atau tidak.
kekacauan
1
@chaos I juga menguji grep -A999999999 'Untracked files'dengan 10.00000 baris sebelum pertandingan dan 10.00000 baris setelah pertandingan. Pendekatan itu bekerja dengan baik. Jadi grepbisa melakukannya. Masalah dengan pendekatan Anda adalah bahwa Anda memaksanya untuk melakukan kecocokan tunggal pada seluruh file daripada pada setiap baris.
kasperd
13

Jika Anda tidak keberatan menggunakan sed, berikut adalah solusi yang mungkin

git status | sed -n -e '/Untracked files/,$p'
rahul
sumber
Ini memiliki keuntungan bahwa ia bekerja dengan grep dan sed UNIX biasa, sedangkan solusi yang diterima membutuhkan grep GNU.
Guntram Blohm mendukung Monica
3

Saya akan gunakan awkuntuk ini:

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

Ini /Untracked files/,0adalah kisaran kisaran. Ini mengevaluasi ke True dari pertama kali Untracked filesdan sampai 0mengevaluasi ke True. Karena ini tidak pernah terjadi, ia mencetak sisa file.

Perhatikan bahwa awkperilaku kepada True adalah mencetak catatan saat ini (baris, biasanya), itu sebabnya kami tidak perlu menelepon secara eksplisit print.

fedorqui
sumber
2

Anda dapat mencoba:

git status | grep -A99 Untracked

di mana -Aakan mencetak garis konteks setelah pertandingan.

Sebagai alternatif gunakan moreatau less, misalnya:

git status | less +/Untracked

Untuk tujuan scripting, saya akan menggunakan ex/ vi:

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

Untuk memasukkan baris dengan file yang tidak dilacak , gunakan kd1Gsebagai ganti d1G.

Atau tanpa pipa dan /dev/stdin, sintaks akan: ex ... <(git status).

kenorb
sumber
Saya memang termasuk -Adalam pertanyaan awal saya, tetapi saya suka more +/Untrackedbagian dari jawaban Anda.
alexus
@alexus Jika Anda menulis skrip, saya telah menambahkan versi exyang setara dengan vi -e.
kenorb
terima kasih, saya percaya more/ lesssangat berguna)
alexus
1

Untuk satu-liner dengan tanda kurung untuk menelurkan subkulit sehingga Anda menghindari mempertahankan variabel:

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

Anda bisa langsung menyalurkannya ke hal lain yang perlu Anda lakukan.

Atau Anda dapat menggunakannya dalam skrip shell apa pun

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

Ganti echo "$LINE"dengan apa pun yang ingin Anda lakukan dengan data. Jika Anda ingin melewati jalur "File yang tidak dilacak", maka cukup alihkan kedua tes tersebut.

Hyppy
sumber
0

Anda dapat menggunakan sesuatu seperti ini, saya menggunakan Perl, perintah berikut ini ditetapkan count = 1jika saya mencocokkan beberapa string di baris saat ini dan ketika loop sementara selesai saya memeriksa variabel jumlah dan saya mencetak rentang garis dari mana pertandingan terjadi pada yang terakhir baris

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";}}'
c4f4t0r
sumber
1
Terlalu rumit. Solusi Perl sederhana ada di sini: stackoverflow.com/a/18167194/111036 . Variasi yang mencakup garis yang cocok dapat berupa:perl -ne 'print if /Untracked files:/ .. 0'
mivk