【发布时间】:2010-09-27 06:57:35
【问题描述】:
如何使用 grep 执行搜索,当找到匹配项时,将打印文件名以及该文件中的前 n 个字符?注意n是可以指定的参数,与前n个字符是否实际包含匹配字符串无关。
【问题讨论】:
如何使用 grep 执行搜索,当找到匹配项时,将打印文件名以及该文件中的前 n 个字符?注意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(但它们很陈旧)。我注意到head的POSIX版本只支持-n和行数; -c 选项可能是 GNU 扩展。
【讨论】:
grep -l pattern *.txt |
while read line; do
echo -n "$line: ";
head -c $n "$line";
echo;
done
如果您想查看前n 行而不是字节,请将-c 更改为-n。
【讨论】:
这里有两个想法:
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 --
【讨论】: