链多个“grep -r”调用

时间:2015-12-17 22:32:09

标签: linux grep

我正在尝试查找具有模式X但没有模式Y的所有文件(即文件列表,而不是这些文件中的行列表)。如果我的所有文件都是在一个目录中:

grep X * | grep -vl Y

......但不幸的是他们不是。如果我尝试使用-r选项来递归我的文件系统:

grep -r X * | grep -v Y

它不起作用。如果我抛出-l选项(使其打印文件路径而不是文件中的行),它也不起作用:

grep -rl X * | grep -v Y

但是,我觉得必须有一种方法来组合grep -r次来电,我觉得我已接近解决方案,所以...任何具有更好grep技能的人都可以帮助教我是一个链接这种电话的模式吗?

3 个答案:

答案 0 :(得分:1)

编辑:这不起作用,因为我没有正确创建我的测试用例。见下文。

给出如下设置:

mkdir a
echo "xpat" > a/yes1.txt
echo "xpat noty" > a/yes2.txt
echo "xpat\nypat" > a/no1.txt

mkdir b
echo "something\nelse\nxpat" > b/yes3.txt
echo "ypat\nsomething\nxpat" > b/no2.txt
echo "not that" > b/no3.txt

你想在哪里找到包含xpat而不是ypat的文件(三个是?.txt文件):

grep -vl "ypat" `grep -rl "xpat" *`

a/yes1.txt
a/yes2.txt
b/yes3.txt

这是正确的测试用例,但失败了。

mkdir a
echo "xpat" > a/yes1.txt
echo "xpat noty" > a/yes2.txt
echo "xpat
ypat" > a/no1.txt

mkdir b
echo "something
else
xpat" > b/yes3.txt
echo "ypat
something
xpat" > b/no2.txt
echo "not that" > b/no3.txt

grep -vl "ypat" `grep -rl "xpat" *`

a/yes1.txt
a/no1.txt
a/yes2.txt
b/yes3.txt
b/no2.txt

我还在思考为什么。

答案 1 :(得分:1)

此:

grep -r X | grep -v Y | cut -f1 -d':' | uniq

生成所有包含行的文件,其中包含X而不是Y.

此:

grep -rl Y > tmp.x
grep -rl X --exclude-from=tmp.x

生成包含X而不是Y的所有文件。也就是说,X_Files是包含XY_Files的所有文件都是包含Y的文件,它将生成{{1} }。

实施例。设置:

X_Files - Y_Files

第一种情况:

mkdir test && cd test
echo foo      > a.txt
echo foo bar >> a.txt

第二种情况:

$ grep -r foo | grep -v bar
a.txt:foo

什么都不产生。

答案 2 :(得分:1)

我会发布一个新的答案,尽管OP接受了其中一个。因为到目前为止这两个答案并不适用于所有情况。 grep -v不是正确的方法。

首先,举例说明:(省略递归部分只是为了使构建示例更容易)

==> one_two.txt <==
11111111
222222222

==> one.txt <==
1111111111111

==> two.txt <==
22222222222

我们说X1Y2,也就是说,我们要查找包含1的文件但不是2包含one.txt

显然,结果只有kent$ grep -r 1 | grep -v 2 | cut -f1 -d':' | uniq one.txt one_two.txt

答案A :(接受的)

kent$  grep -vl "2" `grep -rl "1" *`       
one_two.txt
one.txt

答案B:

kent$  awk 'NR==FNR{a[$0]++;next} $0 in a{delete a[$0]}END{for(x in a)print x}' <(grep -rl 1) <(grep -rl 2)
one.txt

所以两者都给出了不正确的结果。

工作解决方案:

grep -v pattern

的解释

X是错误的方式,因为如果文件中的任何行与模式不匹配,它将报告匹配。我们想要的是,找到两组文件(匹配Y和匹配XSet - YSet),做一个减法class UINaviationBarCustomHeight: UINavigationBar { // Note: this must be set before the navigation controller is drawn (before sizeThatFits is called), // so set in IB or viewDidLoad of the navigation controller @IBInspectable var barHeight: CGFloat = -1 @IBInspectable var barHeightPad: CGFloat = -1 override func sizeThatFits(size: CGSize) -> CGSize { var customSize = super.sizeThatFits(size) let stockHeight = customSize.height if (UIDevice().userInterfaceIdiom == .Pad && barHeightPad > 0) { customSize.height = barHeightPad } else if (barHeight > 0) { customSize.height = barHeight } // re-center everything transform = CGAffineTransformMakeTranslation(0, (stockHeight - customSize.height) / 2) resetBackgroundImageFrame() return customSize } override func setBackgroundImage(backgroundImage: UIImage?, forBarPosition barPosition: UIBarPosition, barMetrics: UIBarMetrics) { super.setBackgroundImage(backgroundImage, forBarPosition: barPosition, barMetrics: barMetrics) resetBackgroundImageFrame() } private func resetBackgroundImageFrame() { if let bg = valueForKey("backgroundView") as? UIView { var frame = bg.frame frame.origin.y = -transform.ty if (barPosition == .TopAttached) { frame.origin.y -= UIApplication.sharedApplication().statusBarFrame.height } bg.frame = frame } } }