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

Идея такова: у меня есть документ с данными, перечисленными следующим образом (показано ниже), и я хочу удалить любую строку со значением 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).

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

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, чтобы в любом операторе печати был добавлен этот разделитель. Если октнум опущен, устанавливает $\ к текущей стоимости $/,
  • -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
Другие вопросы по тегам