2016-09-25 2 views
1

Я перебираю CSV-файл. Каждая строка файла отформатирован что-то вроде этого (это Open Street Maps данные):Распечатать, изменить, снова распечатать Bash variable

planet_85.287_27.665_51a5fb91, AcDbEntity: AcDbPolyline, {[имя] Purano автобусный парк-Thimi [тип] маршрут [маршрут ] микроавтобусами [ссылка] 10} {[Id] 13,0 [SRID] 3857 [FieldsTableId]

Это следует формат:

слой, подклассы, ExtendedEntity, Linetype, EntityHandle, Текст

Я хочу добавить новый столбец для Name. Я могу найти имя в строке, отрезав все до [name] и after [. Этот код успешно создает новый строковый файл всех имен (который я открываю как CSV, а затем копирую-вставляю в исходный файл в качестве нового столбца).

cat /path/to/myfile.csv | while read line 
    do 
    if [[ ${line} == *"name"* ]] 
     then 
      printf "$(echo $line | LC_ALL=C sed 's/^.*name\]//g'| LC_ALL=C cut -f1 -d'[') \n" 
     else 
      printf "\n" 
    fi 
done >/path/to/newrow.csv 

Эта система явно субоптимальна - я бы предпочел напечатать всю итоговую строку. Но когда я заменю эту строку printf следующим образом:

printf "$line,$(echo $line | LC_ALL=C sed 's/^.*name\]//g'| LC_ALL=C cut -f1 -d'[') \n" 

Он печатает строку, но не имя. Я попробовал распечатать их в отдельных операторах печати, распечатать строку и затем повторить имя, сохранить имя в переменной, а затем распечатать, а также ряд других методов, и каждый раз, когда я либо: а) печатаю только строку, либо б) напечатайте имя на новой строке, которая разбивает формат CSV.

Что я делаю неправильно? Как распечатать полную исходную строку с именем, добавленным в конце в конце столбца?

Примечание: Я бегу это в терминале на MacOs Sierra на MacBook Pro 15" Retina

+1

FYI - используя 'printf', замены должны быть только в последующих аргументах, а не в самой строке формата. –

+1

... и запускать 'sed' и' cut' один раз в строке очень, * очень * неэффективно - если вы собираетесь выполнять свою обработку поэтапно, попробуйте использовать [bash-native string manipulation] (http://mywiki.wooledge.org/BashFAQ/100). –

+0

@CharlesDuffy спасибо за ввод. Завтра я прочитаю еще несколько справочных страниц. Я занял очень строгий класс на Bash и C, но это было, возможно, 5 месяцев назад, и с тех пор я не делал этого, поэтому на данный момент я совершенно не в курсе! –

ответ

1

Если я правильно понимаю, вы хотите, чтобы извлечь имя между [name] и [type], и добавить в качестве нового последнего CSV. . колонка Вы можете сделать это с помощью группы захвата:.

sed -e 's/.*\[name\] \(.*\) \[type\].*/&,\1/' < input 

Обратите внимание на \(.*\) в середине Это захватывает текст между [name] и [type]

.

В заменяющей строке & обозначает согласованную строку, которая является всей строкой, так как рисунок начинается и заканчивается .*. Далее , - буквальная запятая, а \1 - это содержимое первой группы захвата, часть которой соответствует \(...\).

+0

Это сработало, спасибо. Тем не менее, пользователи macOS должны добавить LC_ALL = C при использовании sed и других подобных инструментов в oder, чтобы избежать предупреждений. –

+1

Не нужно. Это зависит от настройки вашей среды. Я тоже на OSX, и мне не нужно было добавлять его, и у меня есть «LC_ALL = en_US.UTF-8' – janos

+0

интересный - вы сделали что-то особенное, чтобы настроить свою машину на использование более стандартного SED? Или это то, что я нахожусь в Сьерра, который использует версию BSD? –

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