अंत तक मैच के बाद grep लाइनें


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जीएनयू में पैरामीटर की तरह, लाइनों की संख्या निर्दिष्ट किए बिना 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तर्क के रूप में एक बड़ी संख्या के साथ उपयोग क्यों नहीं कर सकते हैं ?
कास्परड

जवाबों:


17

GNU के साथ grep(संस्करण 2.6.3 के साथ परीक्षण किया गया):

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

-Pपर्ल रेगुलर एक्सप्रेशंस के लिए उपयोग करता है , -zसाथ ही न्यूलाइन के साथ मेल खाता है \nऔर -oकेवल प्रिंट करता है कि पैटर्न से क्या मेल खाता है।

रेगेक्स ने समझाया :

पहले हम स्ट्रिंग के होने तक किसी भी वर्ण ( .) शून्य या कई बार ( *) से मेल खाते हैं Untracked files। अब, ब्रैकेट के अंदर का हिस्सा (.*\n)किसी भी चरित्र को एक नई रेखा ( .) शून्य या कई बार ( *) के बाद एक नई पंक्ति ( \n) को छोड़कर मेल खाता है । और वह सब (जो कि बैकसेट के अंदर होता है) शून्य या कई बार हो सकता है; यही अंतिम का अर्थ है *। पहली घटना के बाद, अब इसे अन्य सभी लाइनों से मेल खाना चाहिए Untracked files


3
एक उत्तर जो वास्तव में उपयोग करता है grep, मैं प्रभावित हूं!
ह्यपी

@ मेरे लिए भी) और फिर फिर, मैच भी विकसित हुआ पर्ल
रेक्सक्स

1
यदि इनपुट में बहुत सारी लाइनें हैं तो यह अच्छी तरह से काम नहीं करता है। मैंने इसे Ubuntu 14.04 पर परीक्षण किया, और यदि मैच लगभग 8000 लाइनों से अधिक लंबा है, तो यह segfaults है।
कैस्परर्ड

2
@kasperd मुझे लगता है कि 8000+ लाइनों के साथ, grepसही उपकरण नहीं है। लेकिन अन्यथा यह सवाल उपयोगकर्ता के लिए है (मुझे लगता है) केवल प्रासंगिक आउटपुट को देखने के लिए, आपके पास स्पष्ट रूप से 8000+ लाइनें, grepएड या नहीं हैं।
अराजकता

1
@ कोच grep -A999999999 'Untracked files'ने मैच से पहले 1000000 लाइनों और मैच के बाद 1000000 लाइनों के साथ भी परीक्षण किया । उस दृष्टिकोण ने ठीक काम किया। तो grepकर सकते हैं। आपके दृष्टिकोण के साथ समस्या यह है कि आप इसे व्यक्तिगत लाइनों के बजाय संपूर्ण फ़ाइल पर एकल मैच करने के लिए मजबूर कर रहे हैं।
कैस्परर्ड

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एक रेंज एक्सिशन है। यह पहली बार से सही का आकलन Untracked filesऔर जब तक 0सही का आकलन। चूंकि यह कभी नहीं होता है, यह बाकी फाइल को प्रिंट करता है।

ध्यान दें कि awkट्रू का व्यवहार वर्तमान रिकॉर्ड (लाइन, सामान्य रूप से) प्रिंट करना है, इसलिए हमें स्पष्ट रूप से कॉल करने की आवश्यकता नहीं है 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 यदि आप एक स्क्रिप्ट लिख रहे हैं, तो मैंने वह संस्करण जोड़ा है exजिसके साथ बराबर है vi -e
kenorb

धन्यवाद, मेरा मानना ​​है कि more/ lessबहुत उपयोगी है)
एलेक्सा

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

आप इस तरह से कुछ का उपयोग कर सकते हैं, मैंने पर्ल का उपयोग किया है, निम्न कमांड सेट count = 1अगर मैं वर्तमान लाइन में कुछ स्ट्रिंग से मेल खाता हूं और जब लूप समाप्त हो जाता है तो मैं गिनती चर की जांच करता हूं और जहां मैच अंतिम होता है वहां से मैं लाइनों की सीमा प्रिंट करता हूं लाइन

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
बहुत अधिक जटिल। एक सरल पर्ल समाधान यहां है: stackoverflow.com/a/18167194/111036 । एक बदलाव जो मैच के लिए लाइन में शामिल हो सकते हैं:perl -ne 'print if /Untracked files:/ .. 0'
mivk
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.