dòng grep sau trận đấu cho đến khi kết thúc


12

Tôi có đầu ra sau git status, làm thế nào để tôi greplàm mọi thứ sau 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]$ 

Giống như thế này, nhưng không chỉ định số lượng dòng, như -Atham số trong 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ó cách nào để làm điều đó?

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

Tại sao bạn không thể sử dụng -Avới số lượng đủ lớn làm đối số?
kasperd

Câu trả lời:


17

Với GNU grep(được thử nghiệm với phiên bản 2.6.3):

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

Sử dụng -Pcho các biểu thức chính quy perl, -zcũng phù hợp với dòng mới \n-ochỉ in những gì phù hợp với mẫu.

Các regex giải thích :

Đầu tiên, chúng ta khớp bất kỳ ký tự nào ( .) 0 hoặc nhiều lần ( *) cho đến khi xuất hiện chuỗi Untracked files. Bây giờ, phần bên trong dấu ngoặc (.*\n)khớp với bất kỳ ký tự nào ngoại trừ một dòng mới ( .) 0 hoặc nhiều lần ( *) theo sau là một dòng mới ( \n). Và tất cả những gì (đó là bên trong các ví) có thể xảy ra 0 hoặc nhiều lần; đó là ý nghĩa của người cuối cùng *. Bây giờ nó phải phù hợp với tất cả các dòng khác, sau lần xuất hiện đầu tiên của Untracked files.


3
Một câu trả lời thực sự sử dụng grep, tôi rất ấn tượng!
Hyppy

@hyppy tôi cũng vậy) và sau đó, trận đấu cũng phát triển Perl regex)
alexus

1
Điều này không hoạt động tốt nếu đầu vào có nhiều dòng. Tôi đã thử nghiệm nó trên Ubuntu 14.04 và nếu trận đấu dài hơn khoảng 8000 dòng thì nó sẽ bị lỗi.
kasperd

2
@kasperd Tôi nghĩ với hơn 8000 dòng, grepkhông phải là công cụ phù hợp. Nhưng nếu không, câu hỏi này là (tôi nghĩ) cho người dùng chỉ xem đầu ra có liên quan, những gì bạn rõ ràng không có ở hơn 8000 dòng, greped hay không.
hỗn loạn

1
@chaos Tôi cũng đã thử nghiệm grep -A999999999 'Untracked files'với 1000000 dòng trước trận đấu và 1000000 dòng sau trận đấu. Cách tiếp cận này chỉ hoạt động tốt. Vì vậy, grepcó thể làm điều đó. Vấn đề với cách tiếp cận của bạn là bạn buộc nó phải thực hiện một trận đấu duy nhất trên toàn bộ tệp chứ không phải trên từng dòng riêng lẻ.
kasperd

13

Nếu bạn không phiền khi sử dụng sed, đây là một giải pháp khả thi

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

Điều này có lợi thế là nó hoạt động với grep và sed UNIX đơn giản, trong khi giải pháp được chấp nhận yêu cầu GNU grep.
Guntram Blohm hỗ trợ Monica

3

Tôi sẽ sử dụng awkcho việc này:

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

Đây /Untracked files/,0là một sự căng thẳng phạm vi. Nó đánh giá thành True ngay từ lần đầu tiên Untracked filesvà cho đến khi 0đánh giá thành True. Vì điều này không bao giờ xảy ra, nó in phần còn lại của tập tin.

Lưu ý rằng awkhành vi của True là True để in bản ghi hiện tại (dòng, thông thường), đó là lý do tại sao chúng ta không phải gọi một cách rõ ràng print.


2

Bạn có thể thử:

git status | grep -A99 Untracked

nơi -Asẽ in các dòng của bối cảnh sau khi trận đấu.

Hoặc sử dụng morehoặc less, ví dụ:

git status | less +/Untracked

Đối với mục đích kịch bản, tôi sẽ sử dụng ex/ vi:

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

Để bao gồm dòng với các tệp Unracked , sử dụng kd1Gthay vì d1G.

Hoặc không có đường ống và /dev/stdin, cú pháp sẽ là : ex ... <(git status).


Tôi đã bao gồm -Atrong câu hỏi ban đầu của tôi, nhưng tôi thích more +/Untrackedmột phần câu trả lời của bạn.
alexus

@alexus Nếu bạn đang viết một tập lệnh, tôi đã thêm phiên bản extương đương với vi -e.
kenorb

cảm ơn bạn, tôi tin more/ lessrất hữu ích)
alexus

1

Đối với một lớp lót có dấu ngoặc đơn để sinh ra một lớp con để bạn tránh giữ lại các biến:

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

Bạn chỉ có thể đặt ống ở cuối của nó vào bất cứ điều gì khác mà bạn cần làm với nó.

Hoặc bạn có thể sử dụng nó trong bất kỳ kịch bản shell nào

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

Thay thế echo "$LINE"bằng bất cứ điều gì bạn muốn làm với dữ liệu. Nếu bạn muốn bỏ qua dòng "Unracked files", thì chỉ cần chuyển đổi hai bài kiểm tra.


0

bạn có thể sử dụng một cái gì đó như thế này, tôi đã sử dụng Perl, bộ lệnh sau count = 1nếu tôi khớp một số chuỗi trong dòng hiện tại và khi vòng lặp while kết thúc, tôi kiểm tra các biến đếm và tôi in phạm vi của các dòng từ đó khớp đến cuối cùng hàng

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
Quá phức tạp. Một giải pháp Perl đơn giản có tại đây: stackoverflow.com/a/18167194/111036 . Một biến thể bao gồm dòng phù hợp có thể là:perl -ne 'print if /Untracked files:/ .. 0'
mivk
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.