Я пробую данные выборки из Твиттера, я могу считать каждую строку, но не знаю, какие команды использовать для фильтрации данных как то, как я хочу. Любые предложения.
Входной файл: file.txt
id,created_at,text
842433,2017-05-20 14:45:05,goldring.com was just registered https://t.co/xt9345d
336353,2017-05-20 14:45:04,stretch.com was just registered https://t.co/QBEX965hf
84244e,2017-05-20 14:45:03,"Auctions were started for wantit1.com, wantit2.com, wantit3.com and wantit4.com"
842434,2017-05-20 14:45:02,"Auctions were started for sidefun.com, coffeetec.com, lifeout.com and new-fun-boys.com"
Ожидание вывода:
wantit1
wantit2
wantit3
wantit4
sidefun
coffeetec
lifeout
new-fun-boys
Код я имею:
cat file.txt | while read line;
do
echo "$line" >> out1.txt
done
Для Вашего определенного входа это будет работать:
grep -Po '\s[a-z1-9-]{2,}(?=\..{2,4})' file.txt
-P
: сделайте нас способными использовать, смотрят вперед. -o
: только покажите matchs. \s
: только ищите тех, которые запускаются с пространства [a-z1-9-]{2,}
Сопровождаемый любым буквенно-цифровым знаком или дефисом, по крайней мере 2 или больше. (?=\..{3})
: который будет закончен точкой и 2 - 4 символами (доменный суффикс), но не включает его. Вот вывод:
wantit1
wantit2
wantit3
wantit4
sidefun
coffeetec
lifeout
new-fun-boys
А лучшая идея (на основе Вашего комментария) состоит в том, чтобы использовать:
awk '(/2017-05-20/ && /Auctions were started/)' file.txt | grep -Po '\s[a-z1-9-]{1,}(?=\..{2,4})'
Вот несколько опций.
подход KISS с помощью двух властей:
$ grep 'Auctions were started for' file | grep -o '\S*\.com'
wantit1.com
wantit2.com
wantit3.com
wantit4.com
sidefun.com
coffeetec.com
lifeout.com
new-fun-boys.com
более изящный:
$ perl -lne 'if (/"Auctions were started for (.*)"/) {print for split(/, | and /, $1)}' file
wantit1.com
wantit2.com
wantit3.com
wantit4.com
sidefun.com
coffeetec.com
lifeout.com
new-fun-boys.com
Можно легко достигнуть этого с комбинацией grep
, чтобы найти, что все строки в file.txt
содержащий текст "Аукционы были запущены для", и sed
, чтобы извлечь только доменные имена без TLD и распечатать тот на строку:
grep -Po '(?<="Auctions were started for ).*(?=")' file.txt | sed -r 's/and |,|.com//g;y/ /\n/'
<час> Вот разбивка команды:
grep -Po '(?<="Auctions were started for ).*(?=")' file.txt
Это сканирует file.txt
линию за линией и соответствует чему-либо (.*
), которому предшествует строка "Auctions were started for
и сопровождает другой "
. Нам нужно grep
-P
опция включить регулярные выражения PCRE (иначе, мы не могли использовать (?<=...)
и (?=...)
regex lookarounds), и -o
опция только распечатать подобранную часть строки (исключая lookarounds) вместо целой строки.
На втором шаге, мы передаем вывод по каналу этой первой команды в этот sed
команда:
sed -r 's/and |,|.com//g;y/ /\n/'
Этот sed
строка на самом деле содержит две команды, s/and |,|.com//g
и y/ /\n/
.
Первый, s/PATTERN/REPLACEMENT/
поиски регулярного выражения (расширил regex на самом деле, из-за -r
опция), шаблон and |,|.com
, что означает and
, ,
или .com
. Затем это ничем заменяет это, таким образом, эти шаблоны на самом деле удалены из входной строки. g
в конце включает глобальный поиск и замену вместо того, чтобы просто обработать первое соответствие на каждой строке.
y/CHARACTERS/REPLACEMENTS/
переводит все символы в первом поле к их соответствующим символам во втором поле. Здесь я использую это для простого преобразования всех остающихся пространств в разрывы строки.