Если у меня есть CSV, подобный следующему:

1999, random strings go here, £50.00, 983903893
1957, Another lacklustre line, £99.00, 3983093
1987, Adventure UK, £83.83, 39939
1945, North Wales is the Adrenaline Capital of Europe, £78.99, 83983

Как удалить строку, в которой в поле 2 3 или менее слов. Таким образом, результат будет:

1999, random strings go here, £50.00, 983903893
1945, North Wales is the Adrenaline Capital of Europe, £78.99, 83983

У меня возникает соблазн сказать, что я хотел бы использовать sed, потому что он может изменить файл на месте без необходимости создавать новый файл.

Я знаю, как обращаться ко второму полю и удалять отдельные слова или символы с помощью sed из csv. Например, я мог бы использовать это, чтобы удалить вопросительный знак:

sed -ri ':b s/^([^,]*,[^,]*)\?/\1 /g; t b'

Но как мне сказать сказанному, что я хочу удалить всю строку, если слов три или меньше? Это то, с чем я борюсь. Спасибо.

РЕДАКТИРОВАТЬ: Вот фактический фрагмент файла, обратитесь к нему, а не к моему исходному примеру - он в том же формате, но с разными данными, которые, похоже, повлияли на то, как предлагаемая строка sed в ответе Жана-Франсуа Фабра обрабатывает данные:

142106729748,Rocky Horror Book,http://www.ebay.co.uk/itm/Rocky-Horror-Book-/142106729748,0.99
162189532196,Total Film Issue 10,http://www.ebay.co.uk/itm/Total-Film-Issue-10-/162189532196,0.75
162189528365,Total Film Issue 9,http://www.ebay.co.uk/itm/Total-Film-Issue-9-/162189528365,0.99
172328113931,Captain America 163 Silver Age,http://www.ebay.co.uk/itm/Captain-America-163-Silver-Age-/172328113931,2.5
232069020935,Football Picture Story Monthly,http://www.ebay.co.uk/itm/Football-Picture-Story-Monthly-/232069020935,0.25
262606117082,The geographical Tradition ,http://www.ebay.co.uk/itm/geographical-Tradition-/262606117082,10.0
401182170339,Naruto Official Fanbook,http://www.ebay.co.uk/itm/Naruto-Official-Fanbook-/401182170339,3.0
1
nmh 3 Сен 2016 в 23:58

4 ответа

Лучший ответ

Perl решение:

perl -waF, -i~ -ne 'print if 3 < split " ", $F[1]' -- text.txt
  • -w включает предупреждения
  • -n читает входные данные построчно
  • -a разбивает каждую входную строку в массив @F
  • -F сообщает Perl, как его разделить, в этом случае используется запятая
  • -i изменяет файл на месте, ~ будет использоваться как суффикс для резервной копии

split в скалярном контексте возвращает количество полей.

2
choroba 3 Сен 2016 в 21:11

Sed предназначен для простых замен в отдельных строках, вот и все. Для всего остального вы должны использовать awk:

$ awk -F' *, *' 'split($2,t,/ */)>3' file
1999, random strings go here, £50.00, 983903893
1945, North Wales is the Adrenaline Capital of Europe, £78.99, 83983
0
Ed Morton 4 Сен 2016 в 01:52

Sed делает это (едва, но делает)

sed -r '/^[^,]+, (\w+[, ]){4,}/!d' text.txt

Небольшое объяснение:

  • первое поле пропускается
  • {4,} соответствует 4 или более словам, разделенным пробелом или запятой (следующее поле)
  • команда !d их не удаляет (удаляет несовпадающие)
  • требуется опция -r или некоторые вещи не будут работать, например \w

Результат:

1999, random strings go here, £50.00, 983903893
1945, North Wales is the Adrenaline Capital of Europe, £78.99, 83983

(ну, на самом деле мне пришлось поправить знак фунта вручную :))

Изменить: лучше на случай, если TAB найдет свой путь в файле (спасибо potong)

 sed -r '/^[^,]*,([[:space:]]+[^[:space:],]+){4}/!d'
3
Jean-François Fabre 5 Сен 2016 в 07:39

С awk:

awk -F ', ' '{split($2, arr, " "); if(length(arr)>=4) print}' file.txt
  • split($2, arr, " ") создает массив arr, разделяя второе поле на пробел

  • if(length(arr)>=4) print печатает запись, только если длина массива равна >=4

Пример:

% cat file.txt                                                          
1999, random strings go here, £50.00, 983903893
1957, Another lacklustre line, £99.00, 3983093
1987, Adventure UK, £83.83, 39939
1945, North Wales is the Adrenaline Capital of Europe, £78.99, 83983

% awk -F ', ' '{split($2, arr, " "); if(length(arr)>=4) print}' file.txt
1999, random strings go here, £50.00, 983903893
1945, North Wales is the Adrenaline Capital of Europe, £78.99, 83983
1
heemayl 4 Сен 2016 в 01:49