2014-03-28 4 views
1

Прежде всего, я хотел бы сказать, что я искал исчерпывающе для этого решения. Важно, чтобы я использовал sed или, по крайней мере, сочетание утилит командной строки * nix, чтобы решить эту проблему. В некоторых случаях я имею дело с некорректными CSV-файлами, но я уверен, что он разрешимый. Мне не хватает всего одного куска головоломки.Использование sed для очистки CSV-файла

Я хотел бы построить преобразователь из CSV в трубу. Он должен решить следующие вопросы:

  1. Газа из "," и заменить |
  2. Газа из ", и заменить |
  3. Газа из ," и заменить |
  4. Газа из цитаты в кавычки как : dog,"john "bud" smith",cat (будет dog|john bud smith|cat)
  5. Полоса ,, которые не являются подростковые цитаты и заменить |

я закончил почти все это с командой sed, но я озадачен с запятыми, которые находятся в пределах поля. Скорее всего, лучший способ, но у меня заканчивается творческая мысль по этой теме. Правильное решение будет анализировать эту строку:

1234,"bill","butler","1000,p"r"airie",1234,6789 

в

1234|bill|butler|1000,prairie|1234|6789 

Это то, что я до сих пор:

echo '1234,"bill","butler","1000,p"r"airie",1234,6789' | 
sed -e 's/","/|/g' -e 's/,"/|/g' -e 's/",/|/g' -e 's/"//g' 
+1

как вы отличаете 'дворецкий, 1000' от' 1000, praire' – aelor

+0

Вы можете найти http://programmers.stackexchange.com/questions/166454/can-the-csv-format -be-defined-by-a-regex полезно и актуально для вашего вопроса. – Edward

+1

У вас есть правильно сформированные кавычки внутри кавычек ('' john "" bud "" smith "), как описано в [RFC 4180 Comma-Separated Values] (http://tools.ietf.org/html/rfc4180) иметь дело с? Вы хотите, чтобы эти цитаты удалялись? Что делать, если что-нибудь, о трубах, которые уже появляются во входных данных? Выполнение этой работы очень сложно. –

ответ

0
echo '1234,"bill","butler","1000,p"r"airie",1234,6789' | 
sed -e 's/\([0-9"]\),\([0-9"]\)/\1|\2/g' -e 's/"//g' 

Я определил правило:

, is transformed to the | if it is between numbers or quotes 

, а потом просто вырезать все цитаты

EDIT1 Похоже, мое решение не работает, но есть nice thread на этот вопрос

+0

Если строка '1234," foo77,42bar "' Я думаю, что вторая запятая должна оставаться в выходе, если я правильно понимаю вопрос. – Edward

+0

Да, вы правы, этот сценарий завершится неудачно в этом случае –

+0

Возможно, решение здесь состояло в том, чтобы добавить запятую, если первый символ является цитатой и добавляет запятую, если последний символ является цитатой, а затем выполняет обработку. Мысли? @Girafik –

2

Вы можете использовать perl. Text::Parsewords на помощь:

perl -MText::ParseWords -nle 'print join "|", map {s/"//g; $_} parse_line(",",1,$_);' file 

Для вашего ввода образца, было бы произвести:

1234|bill|butler|1000,prairie|1234|6789 
+0

Это приятное решение, но надеемся сделать все это с помощью только sed. –

+0

@BillButler Я сомневаюсь, что вы сможете добиться этого с помощью 'sed'. Удачи. – devnull

0
#!/bin/bash                                              

l='1234,"bill","butler","1000,p"r"airie",1234,6789' 

has_quote_in_quote() 
{ 
    echo $1 | grep -q '[^,]"[^,]' 
} 

clean_quote_in_quote() 
{ 
    echo $1 | sed -E -e 's/([^,])"([^,])/\1\2/g' 
} 

parse() 
{ 
    echo $1 |grep -E -o '[^"]*|"[^"]*"' 
} 

pipe_unquoted_commas() 
{ 
    for f in $(parse $1); do echo $f|sed -E -e '/^[^"]/s/,/|/g'; done 
} 

while has_quote_in_quote $l; do b=$(clean_quote_in_quote $l); l=$b; done 

echo $(printf "%s" $(pipe_unquoted_commas $b|sed 's/"//g')) 

Бег это дает

1234|bill|butler|1000,prairie|1234|6789 

Это не для меня очевидно, что это что вы хотите, но позвольте мне объяснить, как это работает.

has_quote_in_quote находит любое '' ', которое не является соседним с запятой. Clean_quote_in_quote удаляет все, что он может найти, но если они действительно близки, ему требуется больше одного прохода из-за того, что sed прошел продвинутый символ одиночного кавычки в этом случай - так что случайно или преднамеренно, вы, например, были действительно хорошо выбраны.синтаксический анализ выбирает либо нецитированный, либо цитируемый фрагмент текста, включая кавычки. «Цитируемые кавычки» удаляются во время цикла while, а затем запятые преобразуются в последней строке, а оставшиеся кавычки - удаляются.

// P

 Смежные вопросы

  • Нет связанных вопросов^_^