Используйте sed для использования, “находят и заменяют” для каждого второго возникновения

У меня есть папка с +1000 .dat файлами. И каждый файл содержит много строк следующего типа:

-0.0999999999999659-0.0000000006287859
-0.08999999999997500.8000000006183942
-0.0799999999999841-0.0000000007463807
-0.06999999999999320.0000000008661516
-0.06000000000000230.0000000008640644
-0.05000000000001140.0000000008807621
-0.0400000000000205-0.7000000009575896
-0.02999999999997270.0000000009476864
-0.01999999999998180.0000000009150902
-0.00999999999999090.0000000008144152
0.00000000000000000.0000000007097434
0.00999999999999090.0000000007847500
0.01999999999998180.0000000009030998
0.03000000000002960.0000000009741985

Для всех файлов я хочу преобразовать это в

-0.0999999999999659    -0.0000000006287859
-0.0899999999999750    0.8000000006183942
-0.0799999999999841    -0.0000000007463807
-0.0699999999999932    0.0000000008661516
-0.0600000000000023    0.0000000008640644
-0.0500000000000114    0.0000000008807621
-0.0400000000000205    -0.7000000009575896
-0.0299999999999727    0.0000000009476864
-0.0199999999999818    0.0000000009150902
-0.0099999999999909    0.0000000008144152
0.0000000000000000    0.0000000007097434
0.0099999999999909    0.0000000007847500
0.0199999999999818    0.0000000009030998
0.0300000000000296    0.0000000009741985

Единственная вещь, которая последовательна во всех этих файлах, что второе число (соответствующий второй точке на каждой строке) всегда меньше, чем 1,0 и больше, чем-1.0. Но первое число может принять любое действительное значение.

Я поэтому думал об использовании, "находят и заменяют" только для второй 'точки' следующим образом. Найдите:

0.

Замена:

   0.

Я не знаю, как указать sed только действовать на "вторую точку" на каждой строке. У кого-либо есть хорошая идея о том, как сделать это?

4
задан 14 May 2017 в 11:25

4 ответа

 sed -E s'/(.*[^-])(-?0\.)/\1    \2/' 999.dat

* является жадным и съедает как можно больше символы так \. соответствия всегда последнее строки. [^-] гарантирует что дополнительное - из второго числа входит во вторую группу.

5
ответ дан 23 November 2019 в 11:39

Для замены второго возникновения только используйте 2 модификатор. Таким образом:

$ sed -E 's/-?[[:digit:]][.]/    &/2' file.dat
-0.0999999999999659    -0.0000000006287859
-0.0899999999999750    0.8000000006183942
-0.0799999999999841    -0.0000000007463807
-0.0699999999999932    0.0000000008661516
-0.0600000000000023    0.0000000008640644
-0.0500000000000114    0.0000000008807621
-0.0400000000000205    -0.7000000009575896
-0.0299999999999727    0.0000000009476864
-0.0199999999999818    0.0000000009150902
-0.0099999999999909    0.0000000008144152
0.0000000000000000    0.0000000007097434
0.0099999999999909    0.0000000007847500
0.0199999999999818    0.0000000009030998
0.0300000000000296    0.0000000009741985

Как это работает:

  • -E

    Это говорит, что sed к используемому расширил regex. Это избавляет от необходимости выходить ?.

  • s/-?[[:digit:]][.]/ &/2

    Это ищет дополнительное - сопровождаемый цифрой, сопровождаемой литералом .. В тексте замены четыре пробелов добавляются прежде безотносительно совпавшей строки, обозначенной &.

    Модификатор 2 в конце замены команда говорит sed только заменять второе возникновение шаблона.

Связанные примеры

Еще некоторые примеры, показывающие, как различные замены могут быть сделаны:

$ echo aaaa | sed 's/a/A/1'
Aaaa
$ echo aaaa | sed 's/a/A/2'
aAaa
$ echo aaaa | sed 's/a/A/3'
aaAa
$ echo aaaa | sed 's/a/A/4'
aaaA
$ echo aaaa | sed 's/a/A/g'
AAAA
5
ответ дан 23 November 2019 в 11:39

найдите первую точку :)

sed -r 's/(.*\.[^-\.]*)(-?)0\.(.*)/\1\t\20.\3/' file

Примечания

  • -r используйте ДО
  • s/old/new замена old с new
  • (some chars) сохранить some chars к ссылке позже
  • .* любое количество любых символов
  • \. литерал .
  • [^-\.] любые символы кроме дефиса или .
  • -? дополнительный -
  • \1\t\20.\3 распечатайте сохраненные шаблоны, вкладку, и 0. в корректных местах
2
ответ дан 23 November 2019 в 11:39

Как насчет

$ sed -E 's/(-?0\.[0-9]+)(-?0\.[0-9]+)/\1\t\2/' file
-0.0999999999999659     -0.0000000006287859
-0.0899999999999750     0.8000000006183942
-0.0799999999999841     -0.0000000007463807
-0.0699999999999932     0.0000000008661516
-0.0600000000000023     0.0000000008640644
-0.0500000000000114     0.0000000008807621
-0.0400000000000205     -0.7000000009575896
-0.0299999999999727     0.0000000009476864
-0.0199999999999818     0.0000000009150902
-0.0099999999999909     0.0000000008144152
0.0000000000000000      0.0000000007097434
0.0099999999999909      0.0000000007847500
0.0199999999999818      0.0000000009030998
0.0300000000000296      0.0000000009741985

Как это работает:

  • -?0\.[0-9]+ соответствие 0. сопровождаемый одной или несколькими другими десятичными цифрами и дополнительно предшествовавший -
  • (-?0\.[0-9]+)(-?0\.[0-9]+) получите 2 экземпляра вышеупомянутого
  • \1\t\2 замените ими назад с промежуточной ВКЛАДКОЙ
2
ответ дан 23 November 2019 в 11:39

Другие вопросы по тегам:

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