Я нашел две части информации в сети stackexchange, которые помогли мне прийти к этому рабочему ответу:
Однако код в этом ответе - мой собственный.
Посмотрите историю правок, если хотите больше многословия; я вырезал все лишнее и "шаги по пути".
Я думаю, что лучший способ:
center() {
termwidth="$(tput cols)"
padding="$(printf '%0.1s' ={1..500})"
printf '%*.*s %s %*.*s\n' 0 "$(((termwidth-2-${#1})/2))" "$padding" "$1" 0 "$(((termwidth-1-${#1})/2))" "$padding"
}
center "Something I want to print"
Вывод на терминал шириной 80 колонок:
========================== Something I want to print ===========================
Обратите внимание, что вставка не обязательно должна быть одним символом; на самом деле переменная padding
таковой не является, в приведенном выше коде она длиной 500 символов. Вы можете использовать другую форму вставки, изменив только строку padding
:
padding="$(printf '%0.2s' ^v{1..500})"
Результат в:
^v^v^v^v^v^v^v^v^v^v^v^v^v Something I want to print ^v^v^v^v^v^v^v^v^v^v^v^v^v^
Еще одно удобное использование:
clear && center "This is my header"
Ваши данные состоят из шести;
-полей с разделителями, и вы хотите заменить точки в полях со 2 по 5 (, а не 1 или 6 )запятыми.
Это проще всего сделать с помощьюawk
:
awk -F ';' 'BEGIN { OFS=FS } { for (i=2; i<=5; ++i) gsub("\\.", ",", $i); print }' file
С приведенными примерными данными получается
2019-03-17T11:32:28.143343Z;1234,5678;901,234;567,89012;3456,78;192.168.0.1
Код просто выполняет итерацию полей с разделителями;
-каждой строки ввода и вызывает gsub()
для выполнения глобального поиска и замены (, как вы сделали бы с s/\./,/g
или y/./,/
вsed
)на отдельные поля, по которым повторяется цикл.
Затем распечатывается измененная строка.
Опция -F
устанавливает разделитель полей ввода в виде точки с запятой, и мы используем блок BEGIN
, чтобы также установить разделитель полей вывода на то же значение (, что в противном случае вы получили бы поля, разделенные пробелом -).
Используя sed
, вы можете сделать что-то вроде
sed 's/\./,/2; s/\./,/2; s/\./,/2; s/\./,/2' file
То есть, замените 2-ю точку четыре раза (, какая из них является 2-й точкой, будет меняться при каждой замене, поскольку вы заменяете их ). Однако это предполагает, что количество значений в каждом поле остается постоянным.
Чтобы обойти эту проблему, если в какой-то момент у вас есть более двух -точек, разделенных полем, вы можете
sed 'h; s/^[^;]*;//; s/;[^;]*$//; y/./,/; G;H;x; s/;[^\n]*\n/;/; s/\n.*;/;/' file
Короче говоря, эти команды выполняют
y
). Все точки, которые должны были превратиться в запятые, теперь изменены. Теперь мы должны собрать строку из среднего бита в пространстве шаблонов и исходных данных в пространстве хранения. Создайте (с помощью G;H;x
), чтобы пространство шаблонов содержало
Итак, теперь пространство шаблонов содержит три строки . Удалите все, кроме первого поля в первой строке и новой строки, и замените этот удаленный бит на ;
.
Сделайте то же самое с последней строкой, то есть удалите (теперь одинокую )новую строку и все до последней ;
и замените на ;
.
Готово.
Или вы можете просто использовать код awk
.
Еще один сед с петлей:
sed ':A;s/\([^.]*\.[^.]*\)\.\(.*;[^;]*$\)/\1,\2/;tA' infile
Вы можете подойти к этому с помощью редактора sed
следующим образом:
$ sed -e '
y/./\n/
s/\n\(.*\)\n/.\1./
y/\n/,/
' input.txt
Предпосылка состоит в том, что мы сначала превращаем все точки в символы новой строки, а символ гарантированно отсутствует в пространстве шаблонов. Затем мы меняем последнюю и первую новую строку обратно на точки. Все остальные символы новой строки преобразуются в запятые.
ХТН.
Поскольку другие ответы делают предположения о входных данных которые не указаны в вопросе (например, что это набор;
-отдельных значений, или что имеется ровно шесть точек ), Я дам этот немного неуклюжий ответ который делает то, о чем просит вопрос:
sed 's/^\([^.]*\.[^.]*\)\.\([^.]*\)\.\([^.]*\)\.\([^.]*\)\./\1,\2,\3,\4,/'
Это разбивает каждую строку ввода следующим образом:
.
, затем один.
(первый в строке ), затем другая произвольно длинная последовательность символов, кроме .
, .
(второй в строке ), .
, .
(третий в строке ), .
, .
(четвертый в строке ),.
, .
(пятый в строке ), $
). И заменяет его на
.
в строке (включая первый ), ,
(заменяет второй .
), .
и третьей, ,
(заменяет третий .
), .
и четвертой, ,
(заменяет четвертый .
), .
и пятой, ,
(заменяет пятый .
), .
. Таким образом, он заменяет вторую, третью, четвертую и пятую точки запятыми.
Вот еще один подход, специально предназначенный для GNU sed:
sed 's/\./\n/6g; s/\./,/2g; s/\n/./g'
s/\./\n/6g
заменяет все точки, начиная с шестой, на новые строки. s/\./,/2g
заменяет все точки, начиная со второй, запятыми. Но это действительно только со второго по пятый, поскольку первая команда удалила все точки после пятой (, если они есть ). s/\n/./g
заменяет все символы новой строки на точки. Конечно,единственные новые строки в строке те, которые изначально были точками, так что это просто меняет их обратно на то, что они были. Итак, если в строке всего три точки, это изменит второй и третий (хотя четвертого и пятого не существует ).
Предупреждение:Поведение комбинации числа и g
как флаги в команде s
не указаны в POSIX и может варьироваться в зависимости от реализации. Вот как это работает для GNU SED, как описано в руководстве GNU SED .