Присоединение нескольких команд sed в одном скрипте для обработки CSV-файла

Наличие файла CSV следующим образом:

HEADER
"first, column"|"second "some random quotes" column"|"third ol' column"
FOOTER

и ищет результат, например:

HEADER
first, column|second "some random quotes" column|third ol' column

, другими словами, удаление «FOOTER», цитаты в начале, в конце и вокруг |.

Пока этот код работает:

sed '/FOOTER/d' csv > csv1 | #remove FOOTER
sed 's/^\"//' csv1 > csv2 | #remove quote at the beginning
sed 's/\"$//' csv2 > csv3 | #remove quote at the end
sed 's/\"|\"/|/g' csv3 > csv4 #remove quotes around pipe

Как вы видите, проблема заключается в создании 4 дополнительных файлов.

Вот еще одно решение, цель которого - не создавать лишние файлы и делать одно и то же в одном скрипте. Это не работает очень хорошо.

#!/bin/ksh

sed '/begin/, /end/ { 
        /FOOTER/d
        s/^\"//
        s/\"$//
        s/\"|\"/|/g 
}' csv > csv4
27 голосов | спросил Bor 12 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowSat, 12 Sep 2015 15:36:00 +0300 2015, 15:36:00

2 ответа


33

Прежде всего, как показал Майкл, вы можете просто объединить все это в одну команду:

sed '/^FOOTER/d; s/^\"//; s/\"$//; s/\"|\"/|/g' csv > csv1

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

  sed -e '/^FOOTER/d' -e 's/^\"//' -e 's/\"$//' -e 's/\"|\"/|/g' csv > csv1

Тем не менее, похоже, что ваши поля определены |, и вы просто хотите удалить " вокруг всего поля, оставив те, которые находятся внутри поля. В этом случае вы можете сделать:

$ sed '/FOOTER/d; s/\(^\||\)"/\1/g; s/"\($\||\)/\1/g' csv 
HEADER
first, column|second "some random quotes" column|third ol' column

Или, с GNU sed:

sed -r '/FOOTER/d; s/(^|\|)"/\1/g; s/"($|\|)/\1/g' csv 

Вы также можете использовать Perl:

$ perl -F"|" -lane 'next if /FOOTER/; s/^"|"$// for @F; print @F' csv 
HEADER
first, column|second some random quotes column|third ol' column
ответил terdon 12 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowSat, 12 Sep 2015 15:53:09 +0300 2015, 15:53:09
12

Это также сработает:

sed 's /^ "//; s /" | "/| /g; s /" "$ /" /'

Пример:

$ echo '"this"|" and "ths""|" and "|" this 2"|" also "this", "thi", "and th""' | 
sed 's/^"//; s/"|"/|/g; s/""$/"/'
this| and "ths"| and | this 2| also "this", "thi", "and th"

красивая версия

sed '
s/^"//
s/"|"/|/g
s/""$/"/
$d
'
ответил Michael Durrant 12 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowSat, 12 Sep 2015 17:00:46 +0300 2015, 17:00:46

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

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132