如何从命令管道中了解文件名

时间:2015-02-02 12:48:33

标签: bash

我在某个文件列表中搜索一些文本。我有以下命令来打印这些行:

ls -1 *.log | xargs tail --lines=10000 | grep text_for_search

命令输出包含text_for_search的所有出现,但它没有来自哪个文件的信息。如何修改命令以提供此信息?


实际上日志文件的大小是千兆字节,因此对每个文件使用tail --lines=10000至关重要

4 个答案:

答案 0 :(得分:2)

您可以使用循环代替,它将跟踪您的文件名:

for file in *.log; do 
    if tail --lines=-10000 "$file" | grep -q text_for_search; then
        echo "$file"
    fi
done

-q切换到grep会抑制输出,如果模式匹配则返回0(成功)退出代码。

答案 1 :(得分:2)

您可以使用find命令:

find . -name "*.log" -exec grep text_for_search '{}' \;

grep将输出文件名和匹配的行。如果你只需要文件名 - 将-l switch添加到grep命令。

'{}' - 用于find的-exec命令中匹配文件名替换的宏, \;表示命令的参数结束,由exec

调用

答案 2 :(得分:1)

您必须避免解析ls输出并使用shell的for循环来遍历所有*.log个文件:

for f in *.log; do
  awk -v c=$(wc -l < "$f") 'NR>c-10000 && /text_for_search/{print FILENAME ":" $0}' "$f"
done

修改

您可以使用awk搜索所有*.log个文件:

awk 'NR>=10000 && /text_for_search/ {print FILENAME ":" $0}' *.log

答案 3 :(得分:1)

将tail命令替换为:

awk '{v[NR]=$0}END{for(i=NR-10000;i<=NR;i++)print FILENAME,v[i]}'

以上只是替换tail命令,除了它在每行的开头添加一个文件名。