Замените все происшествия \кроме \N

По-видимому, запаздывающие новые строки считаются как символ также.

Предположим, что Вы хотите счетчик символов на каталог, можно сделать

$ find -type d -exec bash -c 'echo -n $0 | wc -m' {} \; 
1
12
27

Который составляет в целом 40, что Вы ищете. Обратите внимание что echo -n удаляет запаздывающие новые строки.

Подведение итогов этих трех также возможно.

$ find -type d -exec bash -c 'echo -n $0 | wc -m' {} \; | awk '{S+=$1} END  {print(S)}'
40
3
28.07.2013, 23:52
4 ответа

Я не то, что сведущий в sed. Но это может быть сделано легко в perl использование regex lookaround:

perl -pe 's/\\(?!N\b)/#/g' your_file_here

Это распечатает измененный файл к stdout. Для создания замен на месте можно сделать:

perl -pi -e 's/\\(?!N\b)/#/g' your_file_here

В основном это заменяет любой обратной косой чертой, не сопровождаемой N\b (символ N на границе слова) с #.

Править

Если Вы абсолютно уверены, что Ваши записи разграничены запятой, можно сделать это для покрытия случая когда \N в конце слова (как в SOLEM\N в примере Вы предоставили):

perl -pe ' s/\\/#/g; s/(\A|,)\s*#N\s*(\Z|,)/$1\\N$2/g;' your_file_here

Это просто занимает место, любая обратная косая черта со знаком "диез" затем ищет #N найденный между двумя запятыми, между началом строки и запятой или между запятой и концом строки.

2
27.01.2020, 21:13
  • 1
    @user2118349, обновленный для взятия пограничного случая, который Вы предоставили во внимание. –  Joseph R. 29.07.2013, 22:13
$ echo '1,2,subjects,\mat\hs,unix\,\Nato,\N,123,\N' \
  | sed -r -e 's@\\([^N]|N[^,])@#\1@g'
1,2,subjects,#mat#hs,unix#,#Nato,\N,123,\N

Редактирование для \N как часть случая слова: (см. комментарии),

$ echo '1,2,subjects,\mat\hs,unix\,\SOLEM\N,\N,123,\N' \
  | sed -r -e 's@,\\N$@,:SINGLE_N_PLACEHOLDER:@g' \
           -e 's@^\\N,@:SINGLE_N_PLACEHOLDER:,@g' \
           -e 's@,\\N,@,:SINGLE_N_PLACEHOLDER:,@g' \
           -e 's@\\@#@g' \
           -e 's@:SINGLE_N_PLACEHOLDER:@\\N@g'
1,2,subjects,#mat#hs,unix#,#SOLEM#N,\N,123,\N

Это ужасно и ненадежно (строка заполнителя должна быть уникальной, прекратит работать, если тот шаблон появится в тексте), но я не нашел рабочий способ сделать утверждения использования sed путем, PCRE/Perl поддерживают их.

Вы могли сделать его короче как так:

$ echo '1,2,subjects,\mat\hs,unix\,\SOLEM\N,\N,123,\N' \
  | sed -r -e 's@\\@#@g' \
           -e 's@(,|^)#N(,|$)@\1\\N\2@g'
1,2,subjects,#mat#hs,unix#,#SOLEM#N,\N,123,\N

Но в этом случае, сингл #N заполнитель, который не должен уже появляться в строке.

2
27.01.2020, 21:13
  • 1
    Обратите внимание, что это повредится, если будет пространство между \N и , следующий за этим. –  Joseph R. 28.07.2013, 23:13
  • 2
    я думал об использовании отрицания конца слова \> после N но, может казаться, не понимает это. Какие-либо идеи? –  unxnut 28.07.2013, 23:18
  • 3
    @unxnut я не думаю, что это возможно потому что \> не действительно символ, который может отрицаться: это соответствует месту в regex (место между словесным символом и несловом одно). Я знаю perl предлагает отрицаемую граничную привязку к слову (\B) но я не уверен если sedBREs поддерживают его. –  Joseph R. 28.07.2013, 23:21
  • 4
    я уверен, должен быть способом инвертировать весь шаблон или строку поиска; в этом случае строка поиска \\N\>. Я просто надеюсь, что некоторый человек типа гуру может дать возможность выполнения его или сказать, почему это не может быть сделано. –  unxnut 28.07.2013, 23:25
  • 5
    @frostschutz Ценит быструю справку, которая предложила, я - новое для регулярного выражения. Не был бы sed-r-e 's@ \([^N] |N [^]) @#\\, 1@g' перестал работать, whenvever \N появился бы в конце строки, например, 1,2, предметы, \mat\hs, Unix \,\SOLEM\N, \N, 123, \N –  user2118349 28.07.2013, 23:54
sed -e 's@\\\([^N]\|\(N[a-zA-Z]\|$\)\)@#\1@g' your_file_here

Объяснение: Замените все \ сопровождаемый

  • что-либо нет N,
  • или N сопровождаемый любой буквой в [a-zA-Z] (расширьте это в случае необходимости),
  • конец строки

с # и остальная часть шаблона соответствия.

2
27.01.2020, 21:13
$ echo '1,2,subjects,\mat\hs,unix\,\Nato,\N,123,\N'   | 
         sed -r -e 's/\\N/XELI/g' | 
         sed -e 's/\\/#/g' | 
         sed -e 's/XELI/\\N/g'
1,2,subjects,#mat#hs,unix#,\Nato,\N,123,\N

Я нахожу, что он больше четко разделяет его:

  • замените \N некоторыми не происходящий символ,
  • затем замените / #
  • и замените/N назад
1
27.01.2020, 21:13
  • 1
    Добро пожаловать в SX :). Вы не работали вокруг \Nato случай упоминается в OP. –  Joseph R. 28.07.2013, 23:39

Теги

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