Как отфильтровать данные из txt, использующего grep или sed?

Я пробую данные выборки из Твиттера, я могу считать каждую строку, но не знаю, какие команды использовать для фильтрации данных как то, как я хочу. Любые предложения.

Входной файл: 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
2
задан 21 May 2017 в 17:48

3 ответа

Для Вашего определенного входа это будет работать:

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})'
2
ответ дан 2 December 2019 в 01:36

Вот несколько опций.

подход 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
3
ответ дан 2 December 2019 в 01:36

Можно легко достигнуть этого с комбинацией 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 в конце включает глобальный поиск и замену вместо того, чтобы просто обработать первое соответствие на каждой строке.

1133-секундный, y/CHARACTERS/REPLACEMENTS/ переводит все символы в первом поле к их соответствующим символам во втором поле. Здесь я использую это для простого преобразования всех остающихся пространств в разрывы строки.

2
ответ дан 2 December 2019 в 01:36

Другие вопросы по тегам:

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