2

Я не носитель английского языка, поэтому я надеюсь, что будет ясно.

Я знаю о grep -C 2 "TARGET" inputfile для выбора 2 строк до и после строки TARGET, но я не могу использовать его для решения своей проблемы. У меня есть файлы, структурированные так

1 0 value1 value2 value3
2 H value1 value2 value3
3 H value1 value2 value3
4 H value1 value2 value3
5 H value1 value2 value3
6 0 value1 value2 value3
7 0 value1 value2 value3
8 H value1 value2 value3
9 0 value1 value2 value3

с несколькими рядами. Требуемое решение будет такой файл

X X X X X
1 0 value1 value2 value3
2 H value1 value2 value3 *
3 H value1 value2 value3 
4 H value1 value2 value3

1 0 value1 value2 value3
2 H value1 value2 value3
3 H value1 value2 value3 *
4 H value1 value2 value3 
5 H value1 value2 value3

... all the other till

6 0 value1 value2 value3
7 0 value1 value2 value3
8 H value1 value2 value3 *
9 0 value1 value2 value3
X X X X X

где TARGET - "H", * - для обозначения выбранной строки (но мне не нужен * в выходном файле), а X - заполнители для настройки количества строк до или после цели! Я пробовал также с awk и sed, без результатов.

2 ответа2

4

Это даст вам большую часть пути туда:

awk -v n=2 -v target=" H " '
    BEGIN {
        lines[0]=""
        for (i=1; i<=n; i++) {
            lines[i]="X X X X X"
            getline; lines[n+i]=$0
        }
    }
    function rotate(i) {
        for (i=1; i<=n*2; i++) 
            lines[i-1] = lines[i]
        lines[n*2]=$0
    }
    function check(i) {
        if (lines[n] ~ target) {
            for (i=0; i<=n*2; i++) 
                print lines[i]
            print ""
        }
    }
    { rotate(); check() }
    END {
        for (i=1; i<=n; i++) {
            $0 = "X X X X X"; rotate(); check()
        }
    }
' inputfile

выходы

X X X X X
1 0 value1 value2 value3
2 H value1 value2 value3
3 H value1 value2 value3
4 H value1 value2 value3

1 0 value1 value2 value3
2 H value1 value2 value3
3 H value1 value2 value3
4 H value1 value2 value3
5 H value1 value2 value3

2 H value1 value2 value3
3 H value1 value2 value3
4 H value1 value2 value3
5 H value1 value2 value3
6 0 value1 value2 value3

3 H value1 value2 value3
4 H value1 value2 value3
5 H value1 value2 value3
6 0 value1 value2 value3
7 0 value1 value2 value3

6 0 value1 value2 value3
7 0 value1 value2 value3
8 H value1 value2 value3
9 0 value1 value2 value3
X X X X X
4

Тот же подход, что и у Гленна Джекмана, но с круговым буфером вместо вращения буфера на каждом входе:

awk -v N=2 -v TARGET=" H " -v PLACE="X X X X X" '
  function check(n, s,     i) {
    a[n%NN]=s
    if (n>N&&a[(n-N)%NN]~TARGET) {
      for (i=n+1;i<=n+NN;++i)
        print a[i%NN]
      print ""
    }
  }

  BEGIN{
    NN=2*N+1
    a[0]=PLACE
    for (i=1;i<=N;++i) { getline a[i]; a[i+N]=PLACE }
  }

  { check(NR,$0) }

  END{
    for (i=NR+1;i<=NR+N;++i) check(i,PLACE)
  }'

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .