Как заменить одинарный или двойной пробел в текстовом файле между кавычками

Лучший способ, который у меня есть на данный момент, но это не единственный способ

[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]#
2
01.08.2016, 21:03
3 ответа

Учтите это Решение awk методом перебора:

awk -F, -v OFS=, '
  {
    for(i=1;i<=NF;i++)
        if ($i ~ /^".*"$/)
                gsub(" +", ",", $i)
    print $0
  }'

Он сообщает awk о необходимости разбивать записи по запятым - при этом следует отметить, что это приведет к поломке, если какое-либо из ваших полей содержит запятую! - и используя OFS, чтобы сообщить оператору печати, что поля нужно объединить запятыми. Цикл for проходит через каждое поле строки, и если поле начинается с ^ с двойной кавычки, содержит любые символы . * и заканчивается ] $ в двойные кавычки, затем глобально замените в этом поле $ i любое количество пробелов с запятыми. После перебора полей выведите всю запись ( $ 0 ).

1
29.04.2021, 00:11
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;'
2
29.04.2021, 00:11

В 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 , хотя у вас могут возникнуть проблемы, если последний символ ввода не является ".

1
29.04.2021, 00:11

Теги

Похожие вопросы