bash: обработка sed файлов, включая ведущие нули

Я использую скрипт bash для перебора файлов, предварительно определенных в нескольких группах массива в каталоге, чтобы отредактировать файл, если он существует (например, в 1-й группе есть 100 файлов, расположенных от 0001 до 0100). , во второй группе - 50 файлов в порядке от 0001 до 0050 и т.д.).

#an array for the groups
systems=(one two three four)

 # loop over the groups
for file in "${systems[@]}"; do  
      i="1"
      # introduce K var because the files are numbered as 0001 ... 0100
      k=$(printf '%03d' $i)
      while [  $i -le 100 ]; do
        if [ ! -f "${output}/${file}_${k}.pdb" ]; then
          echo 'File '${output}/${file}_${k}.pdb' does not exits!'
          break
        else
          ## edit file via SED
          # to add i-th number on the first string of the file and substitute smth on the last string;
          sed -i -e '1 i\MODEL '$i'' -e 's/TER/ENDMDL/g' ${output}/${file}_${k}.pdb
          ((i++))
        fi
      done
done

Этот скрипт не работает на этапе редактирования SED, но если я опускаю начальные нули в именах файлов и использую внутри скрипта только i-й индекс, то все работает нормально:

 # loop over the groups
for file in "${systems[@]}"; do  
      i="1"
      # put k into comment since filles arranged from 1 to 100 without leading zeros; 
      #k=$(printf '%03d' $i)
      while [  $i -le 100 ]; do
        # the filles arranged from 1 to 100
        if [ ! -f "${output}/${file}_${i}.pdb" ]; then
          echo 'File '${output}/${file}_${i}.pdb' does not exits!'
          break
        else
          ## edit file via SED
          # to add i-th number on the first string of the file
          sed -i -e '1 i\MODEL '$i'' -e 's/TER/ENDMDL/g' ${output}/${file}_${i}.pdb
          ((i++))
        fi
      done
done

person user3470313    schedule 05.04.2019    source источник
comment
Чтобы уточнить ответ Джас ниже: printf -v enumerated "${output}/${file}_%04d.pdb" $i; sed -i -e '1 i\MODEL '$i'' -e 's/TER/ENDMDL/g' $enumerated   -  person Paul Hodges    schedule 05.04.2019
comment
@PaulHodges, пожалуйста, добавьте свой в качестве ответа --- он намного полнее, чем у меня.   -  person jas    schedule 05.04.2019


Ответы (2)


k назначается перед циклом с i

i="1"
# introduce K var because the files are numbered as 0001 ... 0100
k=$(printf '%03d' $i)
while [  $i -le 100 ]; do
   ...
   ((i++))
   ...
done

Переместите присваивание в k внутри цикла.
Альтернативный вариант:

for ((i=1;i<100;i++)); do
   k=$(printf '%03d' ${i})
   ...
person Walter A    schedule 05.04.2019
comment
в яблочко! вот почему мой метод не работал... кстати, не могли бы вы объяснить на своем примере, как на самом деле работает этот метод цикла для ((i=1;i‹9999;i++)); делать ? - person user3470313; 05.04.2019
comment
Это просто цикл while, начинающийся с i=1, добавляющий 1 в каждом цикле и заканчивающийся на 9999. Вы должны удалить ((i++)) внутри цикла, поскольку приращение уже выполнено. - person Walter A; 05.04.2019

ПРИМЕЧАНИЕ: внесено несколько правок.

Здесь нет моих собственных ответов - просто компиляция в единый блок кода, включающая ответы jas (по его просьбе ) и Walter A, которые, вероятно, столкнулись с реальной проблемой -

for file in "${systems[@]}"
do for ((i=1;i<100;i++))
   do printf -v enumerated "${output}/${file}_%04d.pdb" $i 
     if [[ -f "$enumerated" ]
     then sed -i -e "1 i\\MODEL $i" -e 's/TER/ENDMDL/g' $enumerated
     else echo "file not found: '$enumerated''
     fi
  done
done

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

for stub in "${systems[@]}"
do for file in "$output/${stub}"_[0-9][0-9][0-9][0-9].pdb
   do sed -i -e "1 i\\MODEL ${file//[^0-9]/}" -e 's/TER/ENDMDL/g' "$file"
   done
done
person Paul Hodges    schedule 05.04.2019
comment
все еще не работает. на самом деле он создает правильные заполнители, но без каких-либо модификаций sed внутри него. кстати, мне нужно вставить в файл в первой строке значение без начальных нулей (как было показано в моем первом примере). именно поэтому в своем первом посте я предложил определить k и i (без нулей) как две разные переменные - person user3470313; 05.04.2019
comment
Нужно увидеть примеры ваших входов и выходов, с фактическими результатами и желаемыми результатами. Кроме того, попробуйте set -x для отладки вывода, чтобы увидеть, что он на самом деле делает, - person Paul Hodges; 05.04.2019
comment
Обязательно запишите ответ Уолтера, касающийся более важного вопроса. - person Paul Hodges; 05.04.2019