如何使用grep执行搜索,当找到匹配项时,将会打印文件名以及该文件中的前n个字符?请注意,n
是一个可以指定的参数,前n个字符实际上是否包含匹配的字符串无关紧要。
答案 0 :(得分:5)
grep -l pattern *.txt |
while read line; do
echo -n "$line: ";
head -c $n "$line";
echo;
done
如果要查看第一个-c
行而不是字节,请将-n
更改为n
。
答案 1 :(得分: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/"
请注意,此解决方案比其他人提供的解决方案更有效,它可以调用多个进程。
答案 2 :(得分: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
(但它们相当古老)。我注意到head
的POSIX版本仅支持-n
和行数; -c
选项可能是GNU扩展。
答案 3 :(得分: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] head 包含 - verbose [ - v] 开关。它还提供 - null ,以容纳带空格的文件名。还有' - ',用于处理“ - c”等文件名。所以你可以这样做:
grep --null -l targetToMatch -- file1 file2 ... fileN |
xargs --null head -v -c25 --