bash: sed обработка филей, включая ведущие нули - PullRequest
0 голосов
/ 05 апреля 2019

Я использую сценарий 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 filles 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

Ответы [ 2 ]

2 голосов
/ 05 апреля 2019

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})
   ...
2 голосов
/ 05 апреля 2019

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

Здесь нет моих собственных ответов - просто соберите в единый блок кода, включив ответы jas (по его просьбе) и Уолтер 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
...