Можно ли использовать переменную в команде sed в сценарии unix bash [дубликат]

На этот вопрос уже есть ответ здесь:

I пытаюсь решить следующую проблему. С большой помощью других здесь я могу написать и понять простой цикл do в сценариях bash.

Теперь я пытаюсь сделать следующее:

В каталоге «mein_directory» мне нужно сначала выполнить , чтобы

создать, скажем, 10 подкаталогов с именем subdirectories1 ....subdirectories10

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

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

И это моя основная проблема на данный момент, потому что мне нужно изменить конкретное слово, которое на самом деле является числом, и мне нужно изменить это число на приращение, умноженное на количество подкаталогов

, чтобы мой код выглядел так :

#!/bin/bash
increment=10

for i in {1..10}; do
    mkdir subdirectory_$i;
done


for d in */; do
    cp FILE "$d";
done

for j in {1..10}; do
    cd subdirectory_$j/
    increment=increment*$j
    sed -i 's/old_word old_digit/old_word old_digits+increment/g' CONTROL
    cd ../;
done

Допустим, в файле "FILE" в подкаталоге_1

мне нужно изменить следующий

с

Павел 10 на Павел 20

И в подкаталог_2

от

Пола 10 до Пола 30

Пожалуйста, кто-нибудь знает, как это обойти?

Большое спасибо

0
задан 9 January 2015 в 18:26

1 ответ

Давайте скажем old_word маркер известен. Мы можем затем использовать grep получить число из исходного файла:

NUM=$(grep -Po -m1 '(?<=old_word )\d+'  FILE)
  • Это использует регулярные выражения Perl. Это говорит это old_world должен предшествовать некоторым цифрам, но не должен считаться частью фактического соответствия.
  • -o -m1 говорит grep печатать только подобранный раздел (число), и только первое такое соответствие.

Затем можно объединить копирование с модификацией:

for i in {1..10}
do 
    NEXT_NUM=$((NUM + i*increment))
    mkdir subdirectory_$i
    sed -r 's/(old_word )'$NUM'/\1'$NEXT_NUM'/' FILE > subdirectory_$i/FILE
done

Вещи рассмотреть:

  • sed не очень хорошо в арифметике, поэтому если Вы хотите сделать это в рамках самого выражения, рассмотрите использование Perl или Awk.
  • Вы не можете непосредственно сделать a=1*2 в сценариях оболочки для выполнения арифметики. Необходимо включить выражение в $(( )): a=$((1*2)), или используйте ключевые слова как let.
  • Переменные не расширены в одинарных кавычках, но регулярные выражения часто содержат символы, которые имеют особое значение, таким образом, более безопасно использовать одинарные кавычки для выражения и временно оставить их для добавления в нашей переменной.
  • Круглые скобки вокруг (old_word ) отметьте это как sub выражение, которое можно отослать к более позднему использованию \1 (как видно в замене).
2
ответ дан 6 October 2019 в 04:49

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

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