Intereting Posts
Что такое эквивалент шаблона .gitignore регулярного выражения (Big | Small) (State | City) – * \. Csv Кто-нибудь действительно тестировал время автономной работы ноутбука под разными регуляторами процессора? Изменение номера порта по умолчанию для telnet в Linux CentOS подключен к Интернету, но не обновляет Цветное имя Irssi в действии Может ли rpm вызывать внешний скрипт, хранящийся где-то в пакете во время установки? Скрипт CentOS / RHEL Init (pre-changeroot) как получить статистику полученных пакетов на определенном порту udp Как отключить звуковой сигнал по всей системе Как установить пользовательскую библиотеку GMP только для одного пользователя? Ошибка чтения из nslcd: Сброс соединения с помощью одноранговой сети Почему это rm -rf, а не rmdir -rf Переупаковка проприетарного программного обеспечения Простой сценарий оболочки для отправки сообщения сокета Что означает PIP?

Используйте AWK для разделения подстроки на последние n символов на новый столбец

У меня большой файл .csv где мне нужно разделить конкретный столбец на длину строки. Я пытаюсь взять последние 6 символов столбца 2 и переместить их в новый столбец.

Текущий :

 3102017,90131112,0,740 3022017,8903944,90,0 3092017,127037191,475,0 

Желаемый :

 3102017,90,131112,0,740 3022017,8,903944,90,0 3092017,127,037191,475,0 

С совместимым с POSIX awk :

 awk -F, -v OFS=, '{sub(/.{6}$/, OFS "&", $2); print}' 

С помощью POSIX-совместимого sed :

 sed 's/^\([^,]*,[^,]*\)\([^,]\{6\}\)/\1,\2/' 

Они изменяют строки только в том случае, если второе поле имеет длину не менее 6 символов (обратите внимание, что он с радостью изменит 111,123456,333 на 111,,123456,333 оставив второе поле пустым).

KISS-подход, с awk :

 $ awk -F, '{l=length($2); if (l>6) {$2=substr($2,1,l-6) OFS substr($2,l-5)}} 1' OFS=, file 3102017,90,131112,0,740 3022017,8,903944,90,0 3092017,127,037191,475,0 

При реализации sed с поддержкой расширенных регулярных выражений предполагается, что по крайней мере 6 символов в 2-м столбце для всех строк

 $ sed -E 's/,([^,]*)([^,]{6}),/,\1,\2,/' ip.csv 3102017,90,131112,0,740 3022017,8,903944,90,0 3092017,127,037191,475,0 
  • -E для расширенных регулярных выражений, некоторые реализации требуют -r вместо
  • ,([^,]*)([^,]{6}), будет совпадать , 2-й столбец и ,
    • Второй столбец фиксируется в двух группах с последними 6 символами во 2-й группе
  • ,\1,\2, заменить по желанию

С perl , поскольку sed и awk уже приняты:

 perl -F, -lpe 'splice @F, 1, 1, ($F[1] =~ m/^(\d+)(\d{6})$/g); $_ = join ",", @F' file 

С vim , просто для удовольствия:

 :%s/\m,\d*\zs\ze\d\{6},/,/ 
 perl -pe 's/(,.*?,)/$1 =~ s!......,!,$&!r /e' x.csv 
  • замените второе поле ( ,.*?, ) на …
  • результат замены ( =~ s! ...!...!r ) последних 6 цифр ( ...... ) ими и и a ,