Вопрос или проблема
Я пытаюсь использовать grep, чтобы найти только определенную часть строки в файле.
Файл – это огромный CSV-файл, в котором некоторые столбцы содержат JSON с запятыми, поэтому трудно понять, в каком столбце находится то, что я ищу.
Я использую
egrep -o 'opened for client .*\(' filename.csv
и это дает мне полные строки CSV, содержащие в строке искомый термин, проблема в том, что меня интересует либо захватить часть, которая соответствует .*
, либо просто вывести искомый термин и ничего больше.
Так что, если у меня есть строка в CSV:
,,,,,opened for client jdoe (P) and details attached,,,,,,
,,,,,opened for client jjunior (P2) and details attached,,,,,,
пустые столбцы до и после заполнены сотнями другой информации. Для ясности я опускаю это.
Я хочу вывести только
то есть либо
opened for client jdoe
opened for client jjunior
и т.д.
или только
jdoe
jjunior
Как это можно сделать?
Замените ваше .*
на [^(]*
, что соответствует “всё, кроме (
, на максимально возможную длину”:
grep -o 'opened for client [^(]*' filename.csv
Или вы можете использовать другой инструмент и его стандартные функции POSIX:
sed -En 's/^.*(opened for client [^(]*)\(.*/\1/p' filename.csv
Или, поскольку вы уже используете нестандартный флаг -o
, вы можете использовать PCRE с lookahead, чтобы найти что-то, что не включено в результат:
grep -oP 'opened for client .*(?=\()' filename.csv
Учтите, что все эти варианты будут включать любые пробелы, которые могут находиться непосредственно перед вашим завершающим символом (
. Не забудьте исключить их, если они вам не нужны. Например,
grep -oP 'opened for client .*?(?=\s*\()' filename.csv
С помощью pcregrep
или pcre2grep
вы можете использовать -o1
, чтобы вывести то, что было найдено в 1
й группе:
pcre2grep -o1 'opened for client (.*?) \('
Если ваш grep
поддерживает нестандартный -o
, то, возможно, он также поддерживает -P
:
grep -Po 'opened for client \K.*?(?= \()'
Или используйте perl
напрямую (первая p
в pcre2grep
или P
в -P
):
perl -lne 'print $1 while /opened for client (.*?) \(/g'
Если на строку приходится только одно вхождение и входные данные являются допустимым текстом в локали пользователя, вы можете использовать sed
:
sed -n 's/.*opened for client \([^(]*\) (.*/\1/p'
Однако вывод будет отличаться для таких входных данных, как opened for client foo(bar) (P2)
Ответ или решение
Для выполнения задачи захвата и вывода точного совпадения из CSV файла, вы можете использовать несколько различных утилит, таких как grep
, sed
или perl
. Ниже представлены несколько решений.
Использование grep
-
Вывод полной строки, содержащей совпадение:
Если вы хотите вывести только строку, где встречается ваш шаблонopened for client
, вы можете использовать следующую команду:grep 'opened for client' filename.csv
-
Вывод только фразы:
Чтобы вывести только соответствующий текст, без лишних символов, вы можете воспользоваться следующими командами:-
С помощью регулярных выражений:
grep -o 'opened for client [^(]*' filename.csv
Эта команда будет выводить строки вида:
opened for client jdoe opened for client jjunior
-
Если вам нужно вывести только имена (например,
jdoe
,jjunior
), можно использовать:grep -oP 'opened for client \K[^ ]+' filename.csv
Флаг
-P
включает поддержку Perl-совместимых регулярных выражений, а\K
позволяет исключить часть текста из вывода.
-
Использование sed
Если вы предпочитаете sed
, вы можете использовать следующую команду:
-
Вывод только фразы:
sed -n 's/.*\(opened for client [^(]*\).*/\1/p' filename.csv
Это также выведет строки с текстом
opened for client ...
. -
Вывод только имен:
Для получения только имен можно применить:sed -n 's/.*opened for client \([^(]*\) (\(.*\))/\1/p' filename.csv
Это захватит имена и выведет их.
Использование Perl
Если вы хотите использовать Perl для более сложных задач, команда будет выглядеть так:
perl -lne 'print $1 while /opened for client (.*?) \(/g' filename.csv
Эта команда будет выводить исключительно имена.
Заключение
Выбор между grep
, sed
или perl
зависит от ваших личных предпочтений и необходимых задач. Эти команды помогут вам эффективно извлечь и отобразить нужные данные из вашего CSV файла. Не забудьте протестировать команды на вашем конкретном наборе данных, особенно если в вашей CSV могут быть нетипичные символы или форматы.