简体   繁体   English

Linux使用grep打印文件名和前n个字符

[英]Linux using grep to print the file name and first n characters

How do I use grep to perform a search which, when a match is found, will print the file name as well as the first n characters in that file? 如何使用grep执行搜索,当找到匹配项时,将打印文件名以及该文件中的前n个字符? Note that n is a parameter that can be specified and it is irrelevant whether the first n characters actually contains the matching string. 请注意, n是可以指定的参数,前n个字符实际上是否包含匹配的字符串无关紧要。

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

Change -c to -n if you want to see the first n lines instead of bytes. 如果要查看前n行而不是字节,请将-c更改为-n

You need to pipe the output of grep to sed to accomplish what you want. 您需要将grep的输出传递给sed以完成您想要的操作。 Here is an example: 这是一个例子:

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

The number of dots is the number of characters you want to print. 点数是您要打印的字符数。 Many versions of sed often provide an option, like -r (GNU/Linux) and -E (FreeBSD), that allows you to use modern-style regular expressions. 许多版本的sed经常提供一个选项,比如-r(GNU / Linux)和-E(FreeBSD),它允许你使用现代风格的正则表达式。 This makes it possible to specify numerically the number of characters you want to print. 这样就可以在数字上指定要打印的字符数。

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

Note that this solution is a lot more efficient that others propsoed, which invoke multiple processes. 请注意,此解决方案比其他人提供的解决方案更有效,它可以调用多个进程。

There are few tools that print 'n characters' rather than 'n lines'. 很少有工具可以打印'n个字符'而不是'n行'。 Are you sure you really want characters and not lines? 你确定你真的想要角色而不是线条吗? The whole thing can perhaps be best done in Perl. 整个事情也许最好用Perl完成。 As specified (using grep ), we can do: 如指定(使用grep ),我们可以这样做:

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

The quotes around $file preserve multiple spaces in file names correctly. $file周围的引号正确保存文件名中的多个空格。 We can debate the command line usage, currently (assuming the command name is ' ngrep '): 我们现在可以讨论命令行用法(假设命令名称是' ngrep '):

 ngrep pattern n [file ...]

I note that @litb used ' head -c $n '; 我注意到@litb使用' head -c $n '; that's neater than the dd command I used. 这比我使用的dd命令更整洁。 There might be some systems without head (but they'd pretty archaic). 可能有一些系统没有head (但它们相当古老)。 I note that the POSIX version of head only supports -n and the number of lines; 我注意到POSIX版本的head只支持-n和行数; the -c option is probably a GNU extension. -c选项可能是GNU扩展。

Two thoughts here: 这里有两个想法:

1) If efficiency was not a concern (like that would ever happen), you could check $status [csh] after running grep on each file. 1)如果效率不是问题(就像那样会发生),你可以在每个文件上运行grep后检查$ status [csh]。 Eg: (For N characters = 25 .) 例如:(对于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 contains a --verbose [-v] switch. 2)GNU [FSF] 包含--verbose [-v]开关。 It also offers --null , to accomodate filenames with spaces. 它还提供--null ,以容纳带空格的文件名。 And there's '--' , to handle filenames like "-c" . 还有' - ' ,用来处理像“-c”这样的文件名。 So you could do: 所以你可以这样做:

grep --null -l targetToMatch -- file1 file2 ... fileN |
xargs --null head -v -c25 --

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM