Как искать шаблон между строками 1 500 - 2 500?

У меня есть 8 файлов, и каждый содержит приблизительно 2 000 строк. Я хочу искать конкретное слово в этих файлах между номером строки 1 500 - 2 500.

Вывод должен быть похожим:

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 для этой задачи?

2
задан 25.01.2011, 10:24

4 ответа

Попробуйте это:

#!/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 остановит технологические линии в конце диапазона и сэкономит время, не читая остальную часть строк в файле.

1
ответ дан 08.12.2019, 06:30

awk делает то, что Вы хотите:

% awk 'NR < 1500 { next }; NR > 2500 { exit}; \
    /pattern/ { printf("%s:\n%d:%s\n", FILENAME, NR, $0); }' \
    sample_*.txt

чтобы иметь столько пространства, сколько Вы обеспечили в своем желаемом выводе, просто необходимо добавить как многие \n к printf оператору...

3
ответ дан 08.12.2019, 06:30

Без использования awk как насчет некоторого сценария оболочки + sed:

for f in sample_*.txt ; do echo "$f : " ; \
    sed -ne '1500,2500{/pattern/{=;p}}' $f ; \
    echo ; \
done
0
ответ дан 08.12.2019, 06:30

Просто В интересах Науки, я представляю реализацию 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

Можно начать критические замечания... теперь!

0
ответ дан 08.12.2019, 06:30

Теги

Похожие вопросы