Как я могу использовать sed или awk для удаления строк, соответствующих определенным критериям поля? - PullRequest
2 голосов
/ 25 декабря 2011

У меня есть следующие данные:

 1  abc    xyz   -    -    2   mno
 2  lnm    dse   -    -    3   pqr
 3  ebe    aaa   xhd  asw  4   pow
 4  abc    fww   wrw  ffp  3   ffw

Я бы хотел удалить строк, удовлетворяющих следующим двум условиям:

  1. 4-й и 5-й столбцы пустые
  2. Номер строки соответствующей строки не содержится в 6-м столбце любой другой строки

В этом случае строка 1 должна быть удалена. Как я могу сделать это в sed / awk или наиболее подходящем языке сценариев для этого случая.

Ответы [ 3 ]

3 голосов
/ 25 декабря 2011

Может быть что-то подобное может работать -

awk 'NR==FNR{a[$6];next} 
($4 ~ /[- ]/ && $5 ~ /[- ]/) && !($1 in a){next}1' file file

Условие:

Если Column 4 and Column 5 are blank AND Index not present in Column 6, мы пропускаем эту строкуи мы печатаем все остальное.

Объяснение:

Мы используем NR и FNR встроенные переменные и передаем один и тот же файл дважды.При первом запуске мы сканируем файл и сохраняем Column 6 в массиве.next используется для предотвращения выполнения второго оператора pattern{action} до тех пор, пока не будет прочитан первый файл.После того, как файл полностью прочитан, мы проверяем тот же файл на ваше состояние.Если столбец 4 и столбец 5 пустые, мы смотрим на индекс, а если его нет в массиве, то пропускаем строку, используя next, иначе мы ее печатаем.

Тест:

[jaypal:~/Temp] cat file
 1  abc    xyz   -    -    2   mno
 2  lnm    dse   -    -    3   pqr
 3  ebe    aaa   xhd  asw  4   pow
 4  abc    fww   wrw  ffp  3   ffw

[jaypal:~/Temp] awk 'NR==FNR{a[$6];next} ($4 ~ /[- ]/ && $5 ~ /[- ]/) && !($1 in a){next}1' file file
 2  lnm    dse   -    -    3   pqr
 3  ebe    aaa   xhd  asw  4   pow
 4  abc    fww   wrw  ffp  3   ffw
1 голос
/ 25 декабря 2011

Это может работать для вас:

sed -rn 's/^.*(\S+)\s+\S+$/\1/;H;${x;s/^|\n/:/gp}' file | 
sed -r '1{h;d};/^(\s*\S*){3}\s*-\s*-/{G;/^\s*(\S*).*:\1:/!d;s/\n.*//}' - file
 2  lnm    dse   -    -    3   pqr
 3  ebe    aaa   xhd  asw  4   pow
 4  abc    fww   wrw  ffp  3   ffw

Объяснение:

  1. Прочитать файл и построить справочную таблицу из столбца 6, разделенного :
  2. Считайте таблицу (первую строку) в область удержания (HS), а затем снова прочитайте файл.
  3. Когда столбцы 5 и 6 содержат только -.

    • Добавьте таблицу поиска к пространству шаблона (PS)

    • Просмотрите, используя первый столбец в качестве ключа, и, если он не удастся, удалите эту строку.

    • Для всех оставшихся строк удалите справочную таблицу.

1 голос
/ 25 декабря 2011

Возможное решение с использованием perl:

Содержимое script.pl :

use warnings;
use strict;

## Accept one argument, the input file.
@ARGV == 1 or die qq[Usage: perl $0 input-file\n];

my ($lines, %hash);

## Process file.
while ( <> ) {
        ## Remove leading and trailing spaces for each line.
        s/^\s*//;
        s/\s*$//;

        ## Get both indexes.
        my ($idx1, $idx2) = (split)[0,5];

        ## Save line and index1.
        push @{$lines}, [$_, $idx1];

        ## Save index2.
        $hash{ $idx2 } = 1;
}

## Process file for second time.
for ( @{$lines} ) {

        ## Get fields of the line.
        my @f = split /\s+/, $_->[0];

        ## If fourth and fifth fields are empty (-) and first index exists as second 
        ## index, go to next line without printing.
        if ( $f[3] eq qq[-] && $f[4] eq qq[-] && ! exists $hash{ $_->[1] } ) {
                next;
        }

        ## Print line.
        printf qq[%s\n], $_->[0];
}

Запустить скрипт ( infile содержит данные для обработки):

perl script.pl infile

И результаты:

2  lnm    dse   -    -    3   pqr
3  ebe    aaa   xhd  asw  4   pow
4  abc    fww   wrw  ffp  3   ffw
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...