我有 8 个文件,每个文件大约有 2000 行。我想在这些文件中第 1500 行到第 2500 行之间搜索特定的单词。
输出应如下所示:
sample_1.txt :
1510:declare var testing
sample_2.txt :
1610:declare var testing
sample_7.txt :
1610:declare var testing
sample_10.txt :
1710:declare var testing
可以用于grep
这个任务吗?
答案1
尝试这个:
#!/usr/bin/awk -f
BEGIN {
begin = ARGV[1]
end = ARGV[2]
pattern=ARGV[3]
ARGV[1] = ARGV[2] = ARGV[3] = ""
}
NR > end {exit}
NR == 1 {
print FILENAME " :\n"
}
NR >= begin {
if ($0 ~ pattern)
print NR ":" $0
}
像这样调用它:
./rangegrep 1500 2000 'declare var testing' sample*.txt
搜索字符串可以是正则表达式。
编辑:
exit
我从检查行号的范围改为使用akira 的回答因为exit
将停止处理范围末尾的行,并通过不读取文件中的其余行来节省时间。
答案2
awk
做你想做的事:
% awk 'NR < 1500 { next }; NR > 2500 { exit}; \
/pattern/ { printf("%s:\n%d:%s\n", FILENAME, NR, $0); }' \
sample_*.txt
为了在所需的输出中提供尽可能多的空间,您只需\n
在 printf 语句中添加尽可能多的空间......
答案3
如果不采用awk
一些 shell 脚本 + 怎么办sed
?
for f in sample_*.txt ; do echo "$f : " ; \
sed -ne '1500,2500{/pattern/{=;p}}' $f ; \
echo ; \
done
答案4
纯粹出于科学的兴趣,我提出了 的实现,它是和torso
之间的逻辑中间点。head
tail
实际上,正如其他人所指出的,这实际上是不必要的,因为您可以通过head
和的简单组合自己获得所需的输出tail
。
#!/bin/sh
usage () {
printf "$0: $0 [-c <byte> -C <byte>] [-n <line> -N <line>] file [file ... ]\n"
}
while [ $# -gt 0 ] ; do
case "$1" in
-c|--byte-start) shift ; start="$1" ; mode=byte ; shift ;;
-C|--byte-end) shift ; end="$1" ; mode=byte ; shift ;;
-n|--line-start) shift ; start="$1" ; mode=line ; shift ;;
-N|--line-end) shift ; end="$1" ; mode=line ; shift ;;
--) shift ;;
-*) printf "bad option '%s'\n" "$1" ; usage ; exit 201 ;;
*) files=("${files[@]}" "$1") ; shift ;;
esac
done
if [ $start -gt $end ] ; then
printf "end point cannot be before start point\n"
usage
exit 202
fi
head_cmd=
tail_cmd=
end=$((end - start))
if [ $mode = "line" ] ; then
head_cmd="-n $end"
tail_cmd="-n +$start"
elif [ $mode = "byte" ] ; then
head_cmd="-c $end"
tail_cmd="-c +$start"
fi
if [ ${#files[@]} -eq 0 ] ; then
cat - | tail $tail_cmd | head $head_cmd
else
tail $tail_cmd "${files[@]}" | head $head_cmd
fi
为了保持主题性,下面介绍了如何torso
解决这个问题:
torso -n 1500 -N 2500 input_file | grep -n "test"
或者符合要求的输出
for file in sample_{1,2,7,10} ; do
printf "\n\n%s:\n\n" "$file"
torso -n 1500 -N 2500 "$file" | grep -n "test"
done
您现在就可以开始批评了!