Удалить строку из файла perl - PullRequest
0 голосов
/ 13 июня 2019

У меня есть файл с | строкой с разделителями, в которой я хочу добавить проверку значения 8-й позиции, если значение совпадает, я хочу удалить эту строку из файла и, если она не соответствует, я хочу оставить ее в файле.

Ниже приведен формат файла, я хочу удалить все строки, имеющие значение U на 8-й позиции

A|B|DADD|H|O| |123 A Street; Apt.2|U|M
A|B|DADD|H|O| |123 A Street; Apt.2|A|M
A|B|DADD|H|O| |123 A Street; Apt.2|B|M
A|B|DADD|H|O| |123 A Street; Apt.2|U|M 

Как мы можем сделать это на Perl или есть какой-либоКак мы можем использовать Awk или Sed.Но после удаления я хочу распечатать их также.

Я пробовал sed, но сопоставляю файл, который хочу найти в определенной позиции.

sed -i '' "/$pattern/d" $file

Ответы [ 2 ]

2 голосов
/ 13 июня 2019
perl -F'\|' -wlane'print if $F[7] ne "U"' file  > new

С помощью переключателя -a каждая строка разбивается на слова, доступные в массиве @F. Разделитель, на который нужно разделить, может быть установлен с помощью опции -F (по умолчанию это пробел), а здесь это |. Смотрите переключатели в perlrun . Затем мы просто проверяем 8-е поле и печатаем.

Чтобы изменить входной файл на месте добавить -i switch

perl -i -F'\|' -wlane'print if $F[7] ne "U"' file

или используйте -i.bak, чтобы также сохранить (.bak) резервную копию.


Я вижу, что возник вопрос о регистрации тех строк, которые не хранятся в файле.

Один из способов - захватить для них поток STDERR

perl -i -F'\|' -wlane'$F[7] ne "U" ? print : print STDERR $_' file 2> excluded

где файл excluded получает поток STDERR, перенаправленный (в bash) с помощью 2>. Однако это может быть совершенно опасно, поскольку теперь возможные предупреждения скрыты и повреждают файл, предназначенный для исключенных строк (поскольку они также идут в этот файл).

Так что лучше соберите эти строки и напечатайте их в конце

perl -i -F'\|' -wlanE'
    $F[7] ne "U" ? print : push @exclude, $_; 
    END { say for @exclude }
' input > excluded

где файл excluded возвращает все пропущенные (исключенные) строки. (Я переключил -e на -E, чтобы получить say.)

1 голос
/ 13 июня 2019

Похоже, это то, что вы хотите:

$ cat file
A|B|DADD|H|O| |123 A Street; Apt.2|U|M
A|B|DADD|H|O| |123 A Street; Apt.2|A|M
A|B|DADD|H|O| |123 A Street; Apt.2|B|M
A|B|DADD|H|O| |123 A Street; Apt.2|U|M

$ awk -i inplace -F'[|]' '$8=="U"{print|"cat>&2"; next} 1' file
A|B|DADD|H|O| |123 A Street; Apt.2|U|M
A|B|DADD|H|O| |123 A Street; Apt.2|U|M

$ cat file
A|B|DADD|H|O| |123 A Street; Apt.2|A|M
A|B|DADD|H|O| |123 A Street; Apt.2|B|M

Выше используется GNU awk для -i inplace.С другими awk вы бы просто сделали:

awk -F'[|]' '$8=="U"{print|"cat>&2"; next} 1' file > tmp && mv tmp file

Чтобы записать удаленную строку в файл с именем log1:

awk -F'[|]' '$8=="U"{print >> "log1"; next} 1' file

Чтобы зарегистрировать ее и распечатать на stderr:

awk -F'[|]' '$8=="U"{print|"tee -a log1 >&2"; next} 1' file
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...