查找多个命令的管道(grep和文件)

时间:2017-03-15 13:28:20

标签: bash shell pipe

这是我的问题:我正在尝试解析系统上的很多文件以找到一些令牌。我的令牌存储在一个文件中,每行一个令牌(例如token.txt)。我的解析路径也存储在另一个文件中,每行一个路径(例如path.txt)。 我使用findgrep的组合来完成我的工作。这是一次尝试:

for path in $(cat path.txt)
do
    for line in $(find $path -type f -print0 | xargs -0 grep -anf token.txt 2>/dev/null);
    do
       #some stuffs here
    done
done

它似乎工作正常,但我真的不知道是否有其他方法可以让它更快(我是编程和shell的初学者)。

我的问题是:对于find命令找到的每个文件,我想获取所有压缩的文件。为此,我想使用file命令。问题是我需要为findgrep输出file命令。

实现这一目标的最佳方法是什么?总结一下我的问题,我想要这样的事情:

for path in $(cat path.txt)
do
    for line in $(find $path -type f);
    do
        #Use file command to test all the files, and do some stuff
        #Use grep to find some tokens in all the files, and do some stuff
    done 
done

我不知道我的解释是否清楚,我尽力了。

编辑:我读过,执行for循环读取文件很糟糕,但有些人声称执行while read循环也很糟糕。说实话,我有点失落,我无法找到正确的方法来做我的事情。

2 个答案:

答案 0 :(得分:1)

你这样做的方式很好,但这是另一种方法。使用此方法,您不必添加其他循环来迭代配置文件中的每个项目。有一些方法可以进一步简化这一点,但它不具备可读性。

测试一下: 在" $ {DIR} / path"我列出了两个目录(每行一个)。两个目录都包含在与此脚本相同的父目录中。在" $ {DIR} /令牌"文件,我有三个令牌(每行一个)来搜索。

#!/usr/bin/env bash

#
# Directory where this script is located
#
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

#
# Loop through each file contained in our path list
#
for f in $(find $(cat "${DIR}/path") -type f); do
    for c in $(cat "${f}" | grep "$(cat ${DIR}/token)"); do
        echo "${f}"
        echo "${c}"
        # Do your file command here
    done
done

答案 1 :(得分:0)

我认为你需要这样的东西:

find $(cat places.txt) -type f -exec bash -c 'file "$1" | grep -q compressed && echo $1 looks compressed' _ {} \;

示例输出

/Users/mark/tmp/a.tgz looks compressed

此脚本查找places.txt中列出的所有位置,并为找到的每个文件运行新的bash shell。在bash shell内部,它正在测试文件是否被压缩并回显消息(如果是的话) - 我猜你会做其他事情,但你不说什么。

如果你还有很多工作要做,那就更详细地写下另一种写作方式:

#!/bin/bash

while read -r d; do
   find "$d" -type f -exec bash -c '
        file "$1" | grep -q "compressed"
        if [ $? -eq 0 ]; then
           echo "$1" is compressed
        else
           echo "$1" is not compressed
        fi' _ {} \;
done < <(cat places.txt)