Как вывести предыдущую строку файла после поиска конкретной строки? - PullRequest
0 голосов
/ 28 января 2011

Как получить предыдущую строку файла после поиска по одной строке?

Пример: существует файл с именем fore.dat, содержащий:

:Server:APBS

        :Max Blocking queue:20

:Transport:000

        :Server:APBS

        :Max Transactions:10

        :MaxConnections:1

:Transport:001

        :Server:APBS

        :Max Transactions:10

        :MaxConnections:1

:Transport:005
        :Server:BIT

        :Max Transactions:10

        :Max Connections:1

:Transport:004

        :Server:APBS

        :Max Transactions:44440

        :Max Connections:1

:Transport:002

        :Server:BET

        :Max Transactions:10

        :Max Connections:1

:Transport:003

        :Server:APBS

        :Max Transactions:50

        :Max Connections:1

Я хочу напечататьТранспортный номер, содержащий имя сервера в качестве APBS.то есть;вывод как:

:Transport:000

:Transport:001

:Transport:004

:Transport:003

Ответы [ 5 ]

1 голос
/ 29 января 2011

Это похоже на работу для awk и должно работать даже в AIX, где у вас нет gawk ...

% awk -F':' '
/^:Transport:/ {
    transport = $0
}

NF == 3 && $2 == "Server" && $3 == "APBS" {
    printf "%s\n\n", transport
}

' fore.dat


:Transport:000

:Transport:001

:Transport:004

:Transport:003

Пояснение:

  • Звоните awk
  • Считать ':' разделителем полей.
  • Для любых строк, начинающихся с ': Transport:', сохраните всю эту строку как transport.
  • Для любых строк с тремя полями, где второе - «Сервер», а третье - «APBS», выведите последнее сохраненное значение transport, за которым следует пара новых строк.
  • использовать fore.dat в качестве входного файла.

Есть несколько разных способов сделать это. Это только один.

0 голосов
/ 28 января 2011

Учитывая, что вы не используете GNU grep и предполагаете, что не можете установить его, вам придется прибегнуть к другим инструментам. Это скрипт, который я назвал 'sgrep', который, как вы можете видеть из информации о дате, довольно старый, но был написан для Xenix, SunOS (предшествовавших Solaris), HP-UX, AIX и легиона других давно ушедших варианты Unix. Он выполняет работу довольно тщательно - он более всеобъемлющий, чем вам нужно в настоящее время.

:   "$Id: sgrep.sh,v 1.3 1989/05/12 10:24:14 john Exp $"
#
#   Special grep
#   Finds a pattern and prints lines either side of the pattern
#   Line numbers are always produced by ed (substitute for grep),
#   which allows us to eliminate duplicate lines cleanly.  If the
#   user did not ask for numbers, these are then stripped out.
#
#   BUG: if the pattern occurs in in the first line or two and
#   the number of lines to go back is larger than the line number,
#   it fails dismally.

set -- `getopt "f:b:n" "$@"`

case $# in
0)  echo "Usage: $0 [-n] [-f x] [-b y] pattern [files]" >&2
    exit 1;;
esac

number="'s/^\\([0-9][0-9]*\\)   /\\1:/'"
filename="'s%^%%'"      # No-op for sed

f=3
b=3
nflag=no
while [ $# -gt 0 ]
do
    case $1 in
    -f) f=$2; shift 2;;
    -b) b=$2; shift 2;;
    -n) nflag=yes; shift;;
    --) shift; break;;
    *)  echo "Unknown option $1" >&2
        exit 1;;
    esac
done
pattern="${1:?'No pattern'}"
shift

case $# in
0)  tmp=${TMPDIR:-/tmp}/`basename $0`.$$
    trap "rm -f $tmp ; exit 1" 0
    cat - >$tmp
    set -- $tmp
    sort="sort -t: -u +0n -1"
    ;;
*)  filename="'s%^%'\$file:%"
    sort="sort -t: -u +1n -2"
    ;;
esac

for file in $*
do
    {
    ed - $file <<-!
    g/$pattern/.-${b},.+${f}n
    !
    } |
    eval sed -e "$number" -e "$filename" \| $sort |
    case $nflag in
    yes)    cat -;;
    no)     sed 's/[0-9][0-9]*://';;
    esac
done

rm -f $tmp
trap 0
exit 0

Мне пришлось выкопать его из окаменелостей, где я храню древние программы. У меня есть Perl-скрипт, который выполняет в основном ту же работу; Я использую их не очень часто, так как обычно у меня установлен GNU grep.

0 голосов
/ 28 января 2011

grep -B1 APBS <filename> возвращает строку, содержащую APBS, и строку прямо над ней.

grep -B1 APBS <filename>| grep Transport вернет строки с транспортными номерами.

0 голосов
/ 28 января 2011

Перед прочтением строки (actual_line) сохраните имеющуюся строку во временной переменной (previous_line).Когда вы найдете тот, который вам нужен (фактическая_линя - та, которую вы ищете), просто верните предыдущую (предыдущая_линя)

0 голосов
/ 28 января 2011

Вам нужно немного подробнее рассказать о том, на каком языке вы работаете.Я бы просканировал каждую строку файла.Я бы поместил строку «последнее чтение» в буфер.Если следующая строка содержит то, что вы ищете, выведите строку, которая хранится в буфере.

...