如何使用 grep 执行搜索,当找到匹配项时,将打印文件名以及该文件中的前 n 个字符?请注意,这n
是一个可以指定的参数,与前 n 个字符是否实际包含匹配字符串无关。
4 回答
grep -l pattern *.txt |
while read line; do
echo -n "$line: ";
head -c $n "$line";
echo;
done
如果您想查看第一行而不是字节,请更改-c
为。-n
n
您需要将 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/"
请注意,此解决方案比其他人提出的调用多个进程的解决方案要高效得多。
很少有工具可以打印“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 扩展。
这里有两个想法:
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 --