比赛结束后的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]$ 

这样,但不指定行数,例如-AGNU中的参数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),2015年

Answers:


17

使用GNU grep(经过2.6.3版测试):

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

使用-PPerl的正则表达式,-z也匹配换行符与\n-o仅打印什么模式相匹配。

正则表达式解释

首先,我们将任何字符(.)匹配零或多次(*),直到出现字符串为止Untracked files。现在,括号内的部分(.*\n)与除换行符(.)零或多次(*)后跟换行符()之外的任何字符匹配\n。所有这些(在backets内部)可以发生零次或多次;那就是最后的意思*。现在,它应与第一次出现后匹配所有其他行Untracked files


3
实际使用的答案grep,给我留下深刻的印象!
2015年

@hyppy我也是),然后再一次,比赛也发展了Perl regex)
alexus

1
如果输入有很多行,这将无法正常工作。我在Ubuntu 14.04上进行了测试,如果匹配长度超过8000行,则会出现段错误。
卡巴斯德(Kasperd),2015年

2
@kasperd我认为有8000多个行grep是不合适的工具。但是否则,这个问题是(我认为)用户只能看到相关的输出,显然您在8000多个行中grep没有或没有。
2015年

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。
Guntram Blohm

3

我会用awk这个:

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

/Untracked files/,0是范围的超越。从第一次开始Untracked files,它的评估结果为True ,直到0评估为True。由于这种情况永远不会发生,因此它将打印文件的其余部分。

注意,awk将True的行为是打印当前记录(通常是一行),这就是为什么我们不必显式调用的原因print


2

您可以尝试:

git status | grep -A99 Untracked

-A匹配后在哪里打印尾随上下文的行。

或者使用moreless,例如:

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非常有用)
Alexex

1

对于带有括号的单线生成子壳,这样可以避免保留变量:

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

您可以在结束时将其传递到您需要执行的其他任何操作中。

或者您可以在任何shell脚本中使用它

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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.