Как удалить несколько строк из текстового файла, основываясь на переменной в предыдущем столбце?

Идея такова: у меня есть документ с данными, перечисленными следующим образом (показано ниже), и я хочу удалить любую строку, имеющую значение 70 или менее, в 6-м (последнем) столбце. Кроме того, я хочу удалить любую строку после нее с соответствующим 3-м столбцом (координата широты).
Вот улов, после изменения широты (3-й столбец) я хочу возобновить поиск для первого значения sub 70 и затем удалить любые строки аналогичным образом, пока не достигну нового значения широты.

Подвох состоит в том, что не каждая «группа» одинаковых широт имеет одинаковое количество линий, и они не всегда заканчиваются на 48.15 (1-й столбец).

Я пытался использовать параметры sed -z, однако мне трудно создать правильный шаблон строки, который распознает то, что я хочу удалить, и удаляет только до следующей группировки перед перезапуском строки.

6.15 21.31750 29.11549 -70.2565 28.7203 99.00000
8.15 21.31750 29.11549 -90.3238 35.0326 99.00000
10.15 21.31750 29.11549 -84.9625 43.2992 100.00000
12.15 21.31750 29.11549 -77.0993 44.3515 99.00000
14.15 21.31750 29.11549 -70.9164 49.5554 96.00000
16.15 21.31750 29.11549 -82.2717 38.6834 98.00000
18.15 21.31750 29.11549 -83.7156 35.6462 99.00000
20.15 21.31750 29.11549 -83.9505 35.1276 95.00000
22.15 21.31750 29.11549 -167.575 66.1472 57.00000
24.15 21.31750 29.11549 -94.5072 38.15 98.00000
26.15 21.31750 29.11549 -38.9739 69.8479 71.00000
28.15 21.31750 29.11549 -94.5072 38.15 98.00000
30.15 21.31750 29.11549 -28.6407 51.3899 24.00000
32.15 21.31750 29.11549 -43.7269 119.979 2.00000
34.15 21.31750 29.11549 -69.6645 150 0.00000
36.15 21.31750 29.11549 -103.964 150 1.00000
38.15 21.31750 29.11549 42.6041 142.656 0.00000
40.15 21.31750 29.11549 109.056 150 0.00000
42.15 21.31750 29.11549 -14.6037 150 45.00000
44.15 21.31750 29.11549 -118.694 53.7305 94.00000
46.15 21.31750 29.11549 -167.053 115.74 92.00000
48.15 21.31750 29.11549 -171.917 150 66.00000
6.15 20.38500 29.12283 -87.9018 36.2993 100.00000
8.15 20.38500 29.12283 -98.356 43.8404 100.00000
10.15 20.38500 29.12283 -88.9825 46.6824 100.00000
12.15 20.38500 29.12283 -78.2202 44.7168 97.00000
14.15 20.38500 29.12283 -78.1702 42.5794 97.00000
16.15 20.38500 29.12283 -76.6382 40.3678 98.00000
18.15 20.38500 29.12283 -79.449 49.3087 95.00000
20.15 20.38500 29.12283 -137.565 45.7575 66.00000
22.15 20.38500 29.12283 -112.652 37.5735 100.00000
24.15 20.38500 29.12283 -55.8986 43.9287 54.00000
26.15 20.38500 29.12283 -50.4227 48.2312 70.00000
28.15 20.38500 29.12283 -55.8986 43.9287 54.00000
30.15 20.38500 29.12283 -57.3999 98.6111 8.00000
32.15 20.38500 29.12283 -74.2068 150 6.00000
36.15 20.38500 29.12283 17.7038 117.808 5.00000
38.15 20.38500 29.12283 -5.36164 96.0492 0.00000
40.15 20.38500 29.12283 -98.5051 99.8733 42.00000
42.15 20.38500 29.12283 -149.328 41.7056 96.00000
44.15 20.38500 29.12283 -172.026 126.696 92.00000
46.15 20.38500 29.12283 -174.664 150 76.00000
48.15 20.38500 29.12283 -176.269 139.467 31.00000

Так что я бы хотел удалить все с 22.15 до 48.15 в первой группе и с 20.15 до 48.15 во второй.

формат bash идеален, так как я использую GMT5 (принимает только bash).

Любая помощь будет оценена.

2
задан 5 April 2016 в 23:59

1 ответ

Использование Perl:

perl -lane 'if($F[5] < 70 || $F[2] == $x) {$x = $F[2]; next} undef $x; print' file
perl -lane '
    if($F[5] < 70 || $F[2] == $x) {
        $x = $F[2];
        next
    }
    undef $x;
    print
' file
  • -l[octnum]: включает автоматическую обработку окончания строки. У этого есть два отдельных эффекта. Во-первых, он автоматически переключается на $/ (разделитель входных записей) при использовании с -n или -p. Во-вторых, он присваивает $\ (разделителю выходной записи) значение octnum, чтобы в любом операторе печати этот разделитель был добавлен снова. Если значение octnum опущено, для $\ устанавливается текущее значение $/.
  • -a: включает режим автоматического разделения, когда используется с -n или -p. Неявная команда split для массива @F выполняется как первая вещь в неявном цикле while, создаваемом -n или -p.
  • -n: заставляет Perl выполнять следующий цикл вокруг вашей программы, что заставляет его перебирать аргументы имени файла, например, sed -n или awk:

    LINE:
      while (<>) {
          ...             # your program goes here
      }
    
  • -e: может использоваться для ввода одной строки программы;

  • if($F[5] < 70 || $F[2] == $x) {$x = $F[2]; next} print: если шестое поле содержит число меньше, чем 70, или второе поле содержит число, равное $x, присваивает вторым полям значение $x и пропускает следующую запись; в противном случае сбрасывает $x и печатает запись.
% cat file
6.15 21.31750 29.11549 -70.2565 28.7203 99.00000
8.15 21.31750 29.11549 -90.3238 35.0326 99.00000
10.15 21.31750 29.11549 -84.9625 43.2992 100.00000
12.15 21.31750 29.11549 -77.0993 44.3515 99.00000
14.15 21.31750 29.11549 -70.9164 49.5554 96.00000
16.15 21.31750 29.11549 -82.2717 38.6834 98.00000
18.15 21.31750 29.11549 -83.7156 35.6462 99.00000
20.15 21.31750 29.11549 -83.9505 35.1276 95.00000
22.15 21.31750 29.11549 -167.575 66.1472 57.00000
24.15 21.31750 29.11549 -94.5072 38.15 98.00000
26.15 21.31750 29.11549 -38.9739 69.8479 71.00000
28.15 21.31750 29.11549 -94.5072 38.15 98.00000
30.15 21.31750 29.11549 -28.6407 51.3899 24.00000
32.15 21.31750 29.11549 -43.7269 119.979 2.00000
34.15 21.31750 29.11549 -69.6645 150 0.00000
36.15 21.31750 29.11549 -103.964 150 1.00000
38.15 21.31750 29.11549 42.6041 142.656 0.00000
40.15 21.31750 29.11549 109.056 150 0.00000
42.15 21.31750 29.11549 -14.6037 150 45.00000
44.15 21.31750 29.11549 -118.694 53.7305 94.00000
46.15 21.31750 29.11549 -167.053 115.74 92.00000
48.15 21.31750 29.11549 -171.917 150 66.00000
6.15 20.38500 29.12283 -87.9018 36.2993 100.00000
8.15 20.38500 29.12283 -98.356 43.8404 100.00000
10.15 20.38500 29.12283 -88.9825 46.6824 100.00000
12.15 20.38500 29.12283 -78.2202 44.7168 97.00000
14.15 20.38500 29.12283 -78.1702 42.5794 97.00000
16.15 20.38500 29.12283 -76.6382 40.3678 98.00000
18.15 20.38500 29.12283 -79.449 49.3087 95.00000
20.15 20.38500 29.12283 -137.565 45.7575 66.00000
22.15 20.38500 29.12283 -112.652 37.5735 100.00000
24.15 20.38500 29.12283 -55.8986 43.9287 54.00000
26.15 20.38500 29.12283 -50.4227 48.2312 70.00000
28.15 20.38500 29.12283 -55.8986 43.9287 54.00000
30.15 20.38500 29.12283 -57.3999 98.6111 8.00000
32.15 20.38500 29.12283 -74.2068 150 6.00000
36.15 20.38500 29.12283 17.7038 117.808 5.00000
38.15 20.38500 29.12283 -5.36164 96.0492 0.00000
40.15 20.38500 29.12283 -98.5051 99.8733 42.00000
42.15 20.38500 29.12283 -149.328 41.7056 96.00000
44.15 20.38500 29.12283 -172.026 126.696 92.00000
46.15 20.38500 29.12283 -174.664 150 76.00000
48.15 20.38500 29.12283 -176.269 139.467 31.00000
user@user-X550CL ~/tmp % perl -lane 'if($F[5] < 70 || $F[2] == $x) {$x = $F[2]; next} undef $x; print' file
6.15 21.31750 29.11549 -70.2565 28.7203 99.00000
8.15 21.31750 29.11549 -90.3238 35.0326 99.00000
10.15 21.31750 29.11549 -84.9625 43.2992 100.00000
12.15 21.31750 29.11549 -77.0993 44.3515 99.00000
14.15 21.31750 29.11549 -70.9164 49.5554 96.00000
16.15 21.31750 29.11549 -82.2717 38.6834 98.00000
18.15 21.31750 29.11549 -83.7156 35.6462 99.00000
20.15 21.31750 29.11549 -83.9505 35.1276 95.00000
6.15 20.38500 29.12283 -87.9018 36.2993 100.00000
8.15 20.38500 29.12283 -98.356 43.8404 100.00000
10.15 20.38500 29.12283 -88.9825 46.6824 100.00000
12.15 20.38500 29.12283 -78.2202 44.7168 97.00000
14.15 20.38500 29.12283 -78.1702 42.5794 97.00000
16.15 20.38500 29.12283 -76.6382 40.3678 98.00000
18.15 20.38500 29.12283 -79.449 49.3087 95.00000
0
ответ дан 5 April 2016 в 23:59

Другие вопросы по тегам:

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