как добавить "$i" для цикла в команду sed?

bash -c -O extglob 'stat /path/todir/!(.|..)'

-O extglobвключает дополнительные операторы сопоставления с образцом, в том числе !(pattern-list)для отрицания.

[-+]O [shopt_option]
         shopt_option is one of the shell options accepted by the shopt builtin  (see  
         SHELL  BUILTIN  COMMANDS  below). If shopt_option  is  present, -O sets the 
         value of that option; +O unsets it.

If the extglob shell option is enabled using the shopt builtin, several extended pattern matching
operators  are recognized.  In the following description, a pattern-list is a list of one or more
patterns separated by a |.  Composite patterns may be formed using one or more of  the  following
sub-patterns:

      ?(pattern-list)
             Matches zero or one occurrence of the given patterns
      *(pattern-list)
             Matches zero or more occurrences of the given patterns
      +(pattern-list)
             Matches one or more occurrences of the given patterns
      @(pattern-list)
             Matches one of the given patterns
      !(pattern-list)
             Matches anything except one of the given patterns
0
09.04.2021, 09:36
2 ответа

Цитата 'делает так, что переменная интерпретируется буквально как $iвместо 30, 31, 32 и т. д.

Я сделал изменение ниже, заключив все выражение sed в кавычки ":

for (( i=30; i<=44; i++))
do
sed "s/0.340d0/0.${i}0d0/g" 1.txt > temp.txt
cp temp.txt "$i".txt     
done
-2
28.04.2021, 22:53

В вашем коде есть три проблемы:

  1. Вы используете строку в одинарных кавычках в качестве выражения sed, не позволяя оболочке расширять переменную в замещающей части команды s///.

  2. Вы меняете исходный 1.txtфайл на месте, так что даже если переменная была расширена оболочкой, шаблон не будет совпадать во второй раз в цикле (, так как файл был изменен предыдущей итерацией ).

  3. Вы перемещаете файл 1.txtна первой итерации, что приведет к сбою команды sedс ошибкой «Нет такого файла или каталога» на каждой последующей итерации.

Исправление этих трех проблем:

for number in {30..44}; do
    sed '28 s/0\.340d0/0.'"$number"'0d0/' 1.txt >"$number.txt"
done

Обратите внимание, что я также удостоверяюсь, что точка в шаблоне соответствует буквальной точке, а не какому-либо символу (, что и сделал бы ., если бы он не был экранирован как \.или используется как[.]). Я все еще использую одинарную кавычку для вашего выражения sed, но я временно выхожу из нее, чтобы ввести значение в двойных кавычках из переменной оболочки number.

Результат выполнения команды sedзаписывается в имя файла, названное с помощью переменной number.

Вместо того, чтобы адресовать строку по ее номеру, вы также можете использовать тот факт, что она начинается со строки rmin=(, предполагая, что единственная строка , начинающаяся с этой строки):

for number in {30..44}; do
    sed 's/^rmin=.*/rmin=0.'"$number"'0d0/' 1.txt >"$number.txt"
done

То же самое можно было бы сделать немного аккуратнее с помощьюawk:

for number in {30..44}; do
    awk -v num="$number" 'FNR == 28 { printf "rmin=0.%.2d0d0\n", num; next }; 1' 1.txt >"$number.txt"
done

Преимущество этого заключается в том, что он будет правильно вставлять число, даже если оно меньше 10 (, создавая 0.020d0вместо 0.20d0для 2, например ).

Или сопоставление rmin=в начале строки:

for number in {30..44}; do
    awk -v num="$number" '/^rmin=/ { printf "rmin=0.%.2d0d0\n", num; next }; 1' 1.txt >"$number.txt"
done
1
28.04.2021, 22:53

Теги

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