#regex #unix #csv #double-quotes
#регулярное выражение #unix #csv #двойные кавычки
Вопрос:
У меня почти следующая проблема, и я не нашел решения. Это может быть моя файловая структура CSV:
1223;"B630521 ("L" fixed bracket)";"2" width";"length: 5"";2;alternate A
1224;"B630522 ("L" fixed bracket)";"3" width";"length: 6"";2;alternate B
Как вы можете видеть, некоторые из них "
написаны для inch и "L"
во вложении "
.
Теперь я ищу сценарий оболочки UNIX для замены "
(дюйм) и "L"
двойных кавычек на 2 одинарные кавычки, как в следующем примере:
sed "s/$OLD/$NEW/g" $QFILE > $TFILE amp;amp; mv $TFILE $QFILE
Кто-нибудь может мне помочь?
Комментарии:
1. вы пробовали s / » / ‘/g? Или вы просто хотите заменить двойные ссылки на «L» и дюймы?
2. Я просто хочу заменить дополнительные двойные ссылки. Результат должен быть доступен для чтения sqlloader, и некоторые поля могут содержать; как часть текста 🙁
Ответ №1:
Обновление (С помощью perl это проще, поскольку вы получаете полные функции предварительного просмотра)
perl -pe 's/(?<!^)(?<!;)"(?!(;|$))/'"'"'/g' file
Вывод
1223;"B630521 ('L' fixed bracket)";"2' width";"length: 5'";2;alternate A
1224;"B630522 ('L' fixed bracket)";"3' width";"length: 6'";2;alternate B
Использование sed, только grep
Просто используя grep, sed (а не perl, php, python и т.д.), не такое элегантное решение может быть:
grep -o '[^;]*' file | sed 's/"/`/; s/"$/`/; s/"/'"'"'/g; s/`/"/g'
Вывод — для вашего входного файла это дает:
1223
"B630521 ('L' fixed bracket)"
"2' width"
"length: 5'"
2
alternate A
1224
"B630522 ('L' fixed bracket)"
"3' width"
"length: 6'"
2
alternate B
grep -o
по сути, это разделение входных данных на;
- sed сначала заменяет «в начале строки на `
- затем оно заменяет «в конце строки другим `
- затем оно заменяет все оставшиеся двойные кавычки
"
на одинарные совсем'
- наконец, оно возвращает все
"
в начало и конец
Комментарии:
1. У меня нет perl для использования, а в SunOS 5.10 нет опции -o для grep : (
Ответ №2:
Может быть, это то, что вы хотите:
sed "s/([0-9])"([^;])/1''2/g"
То есть: Найдите двойные кавычки ( "
), следующие за числом ( [0-9]
), но не за точкой с запятой ( [^;]
), и замените их двумя одинарными кавычками.
Редактировать: я могу расширить свою команду (сейчас она становится довольно длинной):
sed "s/([0-9])"([^;])/1''2/g;s/([^;])"([^;])/1'2/g;s/([^;])"([^;])/1'2/g"
Поскольку вы используете SunOS, я полагаю, вы не можете использовать расширенные регулярные выражения ( sed -r
)? Поэтому я сделал это таким образом: первая s
команда заменяет весь дюйм "
на ''
, вторая и третья s
одинаковы. Они заменяют все, "
которые не являются прямыми соседями a ;
, на один '
. Я должен сделать это дважды, чтобы иметь возможность заменить второе "
из, например "L"
, потому что между обоими есть только один символ "
, и этому символу уже соответствует ([^;])
. Таким образом, вы также могли бы заменить ""
на ''
. Если у вас есть """
или """"
и т.д. вы должны поместить еще одну (но только еще одну) s
.
Комментарии:
1. Это выглядит почти хорошо. Заменены все дюймы. Но у меня все еще есть проблема с буквой «L», и в некоторых случаях я также обнаружил «Остаток» между разделителями полей. 🙁
2. Что вы имеете в виду под «Rest»? Можете ли вы привести пример?
3. Между дополнительными двойными ссылками есть другие слова, потому что это поле свободного текста / комментариев в исходной базе данных. Таким образом, это может быть «L» или «Rest» или «fippel-пиппель» или что-нибудь еще.
4. @Karsten: Я добавил несколько более длинную версию команды, которая теперь должна работать.
5. Спасибо, bmk. Но «L» и все остальные (например, «fippel-пиппель») по-прежнему имеют двойные ссылки. Поскольку на консоли нет ошибки, я боюсь, что ошибка в вашем sed. Я нашел эту страницу compute.cnr.berkeley.edu/cgi-bin/man-cgi?sed 1 и, похоже, доступна опция -r. Помогает ли это упростить ваше утверждение?
Ответ №3:
Для буквы «L» попробуйте это:
sed "s/"L"/'L'/g"
Для дюймов вы можете попробовать:
sed "s/([0-9])""/1''"/g"
Я не уверен, что это лучший вариант, но я пробовал, и это работает. Я надеюсь, что это полезно.
Комментарии:
1. Это выглядит хорошо во втором. Но в некоторых случаях я уже нашел «остаток» между разделителями полей. 🙁