2

如何使用 grep 执行搜索,当找到匹配项时,将打印文件名以及该文件中的前 n 个字符?请注意,这n是一个可以指定的参数,与前 n 个字符是否实际包含匹配字符串无关。

4

4 回答 4

5
grep -l pattern *.txt | 
    while read line; do 
        echo -n "$line: "; 
        head -c $n "$line"; 
        echo; 
     done

如果您想查看第一行而不是字节,请更改-c为。-nn

于 2008-12-17T06:32:18.333 回答
4

您需要将 grep 的输出通过管道传输到 sed 以完成您想要的操作。这是一个例子:

grep mypattern *.txt | sed 's/^\([^:]*:.......\).*/\1/'

点数是要打印的字符数。许多版本的 sed 通常提供一个选项,例如 -r (GNU/Linux) 和 -E (FreeBSD),允许您使用现代风格的正则表达式。这样可以以数字方式指定要打印的字符数。

N=7
grep mypattern *.txt /dev/null | sed -r "s/^([^:]*:.{$N}).*/\1/"

请注意,此解决方案比其他人提出的调用多个进程的解决方案要高效得多。

于 2008-12-17T06:20:35.457 回答
3

很少有工具可以打印“n 个字符”而不是“n 行”。你确定你真的想要字符而不是线条吗?整个事情可能最好在 Perl 中完成。如指定(使用grep),我们可以这样做:

pattern="$1"
shift
n="$2"
shift
grep -l "$pattern" "$@" |
while read file
do
    echo "$file:" $(dd if="$file" count=${n}c)
done

引号周围$file正确保留文件名中的多个空格。我们可以讨论命令行的用法,目前(假设命令名是' ngrep'):

 ngrep pattern n [file ...]

我注意到@litb 使用了 ' head -c $n'; 这比dd我使用的命令更整洁。可能有一些系统没有head(但它们非常陈旧)。我注意到POSIX版本head只支持-n和行数;该-c选项可能是 GNU 扩展。

于 2008-12-17T06:29:33.707 回答
0

这里有两个想法:

1)如果效率不是问题(就像那样会发生),你可以在每个文件上运行grep后检查$status [csh] 。例如:(对于N个字符= 25。)

foreach FILE ( file1 file2 ... fileN )
  grep targetToMatch  ${FILE} > /dev/null
  if ( $status == 0 ) then
     echo -n "${FILE}:  "
     head -c25 ${FILE}
  endif
end

2) GNU [FSF]头部包含一个--verbose [-v]开关。它还提供--null,以容纳带有空格的文件名。还有'--'来处理像"-c"这样的文件名。所以你可以这样做:

grep --null -l targetToMatch -- file1 file2 ... fileN |
xargs --null head -v -c25 --
于 2008-12-17T08:00:39.640 回答