zgrep для нескольких символов вертикальной черты в группе файлов gz

Один из вариантов — использовать интерфейс perlк iconvи его режим -iдля редактирования на месте:

perl -MText::Iconv -i -pe '
  BEGIN{$i=Text::Iconv->new(qw(cp1252 UTF-8));$i->raise_error(1)}
  $_ = $i->convert($_)'./*.php

В GNU awkвы также можете сделать что-то вроде:

gawk -v cmd='iconv -f cp1252 -t utf-8' -i inplace '
  {print | cmd}; ENDFILE {close(cmd)}'./*.php

Оболочка ksh93также имеет оператор >;для сохранения вывода во временном файле, который переименовывается в перенаправленный файл, если команда выполнена успешно:

for f in *.php; do
  iconv -f cp1252 -t utf-8 < $f >; $f
done
0
14.05.2020, 10:13
3 ответа

Создадим три тестовых файла:

echo 'xyz|abc' > c1
echo 'xyz|abc|wty' > c2
echo 'xyz|abc|wty|asd' > c3
gzip c*

Файлы, содержащие одну трубу в строке:

$ zgrep '^[^|]*|[^|]*$' *.gz
c1.gz:xyz|abc

Для любых других номеров (, включая одну вертикальную черту в строке ), можно использовать следующий шаблон:

Две трубы в линию:

$ zgrep -E '^([^|]*\|){2}[^|]*$' *.gz
c2.gz:xyz|abc|wty

Три трубы в линию:

$ zgrep -E '^([^|]*\|){3}[^|]*$' *.gz
c3.gz:xyz|abc|wty|asd

Две или три трубы в линию:

$ zgrep -E '^([^|]*\|){2,3}[^|]*$' *.gz
c2.gz:xyz|abc|wty
c3.gz:xyz|abc|wty|asd

Макс. три трубы в линию:

$ zgrep -E '^([^|]*\|){,3}[^|]*$' *.gz
c1.gz:xyz|abc
c2.gz:xyz|abc|wty
c3.gz:xyz|abc|wty|asd

Если вам нужно только имя файла, добавьте опцию -l, т.е.zgrep -lE...


Моя версия zgrepне поддерживает рекурсивную опцию -r.

Вы можете использовать findдля обратного поиска и запустить zgrepдля результата:

$ find. -type f -name '*.gz' -exec zgrep -lE '^([^|]*\|){3}[^|]*$' {} \;
./c3.gz
0
28.04.2021, 23:14

Вы можете передать имена файлов в awk и найти количество | -с в каждом. Например :эхо 'A|B|C' |awk -F\| '{печать NF -1}'

0
28.04.2021, 23:14

Если предположить, что в любом заданном файле число столбцов с разделителями|-постоянно, то достаточно проверить первую строку файла, чтобы определить количество столбцов в нем.

Следующее сделает это для файла с именемname.gz:

gzip -dc name.gz | awk -F '|' -v name="name.gz" '{ print NF, name } { exit }'

Таким образом, с помощью простого цикла вы сможете вывести количество столбцов и имена файлов, например, всех файлов, соответствующих шаблону/a/b/c*.gz:

for name in /a/b/c*.gz; do
    gzip -dc "$name" |
    awk -F '|' -v name="$name" '{ print NF, name } { exit }'
done

Если вы хотите выводить только имена файлов с определенным количеством столбцов (n=3, например ), используйте

n=3
for name in /a/b/c*.gz; do
    gzip -dc "$name" |
    awk -F '|' -v n="$n" -v name="$name" 'NF == n { print name } { exit }'
done
1
28.04.2021, 23:14

Теги

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