Лучший способ, который у меня есть на данный момент, но это не единственный способ
[root@virt03 test]# awk 'gsub(/[0-9][0-9]/,":&",$1) gsub(/[0-9][0-9]/,":&",$2)' lab1 | sed 's/://1' | sed 's/://3'
03:40:23 05:20:30
03:40:23 02:21:30
04:40:23 01:20:30
03:42:23 02:20:30
03:41:23 15:20:30
02:40:23 15:20:30
[root@virt03 test]# cat lab1
034023 052030
034023 022130
044023 012030
034223 022030
034123 152030
024023 152030
[root@virt03 test]#
Учтите это Решение awk методом перебора:
awk -F, -v OFS=, '
{
for(i=1;i<=NF;i++)
if ($i ~ /^".*"$/)
gsub(" +", ",", $i)
print $0
}'
Он сообщает awk о необходимости разбивать записи по запятым - при этом следует отметить, что это приведет к поломке, если какое-либо из ваших полей содержит запятую! - и используя OFS, чтобы сообщить оператору печати, что поля нужно объединить запятыми. Цикл for
проходит через каждое поле строки, и если поле начинается с ^
с двойной кавычки, содержит любые символы . *
и заканчивается ] $
в двойные кавычки, затем глобально замените в этом поле $ i
любое количество пробелов с запятыми. После перебора полей выведите всю запись ( $ 0
).
perl -pe 's/".*?"/do{$a = $&; $a =~ s: +:,:g; $a}/ge;'
По сути, это просто глобальная замена регулярного выражения s / regex / replace / g
.
Регулярное выражение ". *?"
, он соответствует каждой подстроке, которая начинается с "
и заканчивается следующим за ним "
.
Сложные части:
e
после g
.) s: regex: replace: g
, которая заменяет любую непустую последовательность пробелов запятой. (Мы не можем использовать тот же разделитель, что и во внешней замене, поэтому мы используем :
вместо /
.) $ &
некоторой другой переменной $ a
, а затем выполнить внутреннюю замену на $ a
и, наконец, выведите $ a
. В достаточно свежей версии Perl можно избежать присвоения вспомогательной переменной. Используя модификатор r
, внутреннюю замену можно выполнить непосредственно на копии совпавшей подстроки $ &
(спасибо Стефану Шазеласу):
perl -pe 's/".*?"/$&=~s: +:,:gr/ge;'
В GNU awk
:
gawk -v RS=\" '
NR % 2 == 0{gsub(/ +/, ",")}
{ORS = RT; print}'
То есть, разделителем записей становится символ "
, а пробелы заменяются только в четных записях.
RT
часть, специфичная для GNU.
То же самое с GNU sed
:
tr '\n"' '"\n' | sed -E '2~2s/ +/,/g' | tr '"\n' '\n"'
Более переносимо:
tr '\n"' '"\n' | sed 'n;s/ */,/g' | tr '"\n' '\n"'
будет работать с некоторыми другими sed
, хотя у вас могут возникнуть проблемы, если последний символ ввода не является "
.