Выберите элементы в списке в группах 2 - Bash

Я пытаюсь выбрать элементы в списке файлов с помощью последовательности. Для этого я создал список всех своих файлов после шаблона в папке:

ls -d -1 /my/path/S1*.zip

Где вывод:

/my/path/S1A_IW_SLC__1SDV_20180412T171648_20180412T171715_021437_024E95_BDA1.zip
/my/path/S1A_IW_SLC__1SDV_20180424T171648_20180424T171715_021612_02540A_BB21.zip
/my/path/S1A_IW_SLC__1SDV_20180506T171649_20180506T171716_021787_025996_98AB.zip
/my/path/S1A_IW_SLC__1SDV_20180518T171649_20180518T171716_021962_025F27_A15C.zip
/my/path/S1A_IW_SLC__1SDV_20180530T171650_20180530T171717_022137_0264C8_5D94.zip
/my/path/S1A_IW_SLC__1SDV_20180611T171651_20180611T171718_022312_026A3D_BBFC.zip
/my/path/S1A_IW_SLC__1SDV_20180623T171652_20180623T171719_022487_026F7C_450E.zip
/my/path/S1A_IW_SLC__1SDV_20180623T171652_20180623T171719_543456_64324F_452W.zip

Я хотел бы создать a forцикл, в который для каждого повторения, файлы обрабатываются в группах два. Так, в первом повторении обрабатываются файл в положении 1 в моем списке и файл в положении 2. Во втором взаимодействии, файле в положении 3 и файле в положении 4, и т.д.

Для создания этого более простым я возьму пример разархивации этих файлов в grousp 2:

for i in $(ls -d -1 /shared/Training/WROC0320_UrbanMapping_Germany/Original/S1*.zip)
do
unzip i
unizp i+1 # Not sure if i+1 works like that in `bash`
done

Проблема, которую я вижу с этим подходом, состоит в том, что в первом повторении он будет работать (i будет 1 и 2) но во втором i будет 2 и 3, и это должно быть 3 и 4.

Мой вопрос затем, как выполнить итерации по результату ls такой путь?

0
задан 9 March 2020 в 16:18

2 ответа

В целом необходимо постараться не выполнять итерации по результатам ls - посмотрите, например,

По сравнению с a for цикл, a while цикл дает Вам намного больше контроля выбора файла и разделителям. Например:

printf '%s\0' my/path/*.zip | while IFS= read -r -d '' f1 && IFS= read -r -d '' f2; do 
  echo 'unzipping files'; echo unzip "$f1"; echo unzip "$f2"
done
unzipping files
unzip my/path/S1A_IW_SLC__1SDV_20180412T171648_20180412T171715_021437_024E95_BDA1.zip
unzip my/path/S1A_IW_SLC__1SDV_20180424T171648_20180424T171715_021612_02540A_BB21.zip
unzipping files
unzip my/path/S1A_IW_SLC__1SDV_20180506T171649_20180506T171716_021787_025996_98AB.zip
unzip my/path/S1A_IW_SLC__1SDV_20180518T171649_20180518T171716_021962_025F27_A15C.zip
unzipping files
unzip my/path/S1A_IW_SLC__1SDV_20180530T171650_20180530T171717_022137_0264C8_5D94.zip
unzip my/path/S1A_IW_SLC__1SDV_20180611T171651_20180611T171718_022312_026A3D_BBFC.zip
unzipping files
unzip my/path/S1A_IW_SLC__1SDV_20180623T171652_20180623T171719_022487_026F7C_450E.zip
unzip my/path/S1A_IW_SLC__1SDV_20180623T171652_20180623T171719_543456_64324F_452W.zip

Здесь printf '%s\0' my/path/S*.zip разворачивает шарик оболочки в список, который однозначно разграничен Нулевым символом (единственный символ, который не может появиться в Unix filepath), и затем каждый read управляйте читает один из них. IFS= сбрасывает разделителя полей - единственный эффект этого состоит в том, чтобы предотвратить reads от разделения ведущего пробела (в очень маловероятном событии, что необходимо обработать такие имена).


Возможно более чистый путь, с помощью set встроенный с шариком оболочки для чтения имен файлов однозначно в позиционный массив параметров $@:

shopt -s nullglob

set -- my/path/S*.zip
while (($# > 1)); do 
  echo "unzipping files"; 
  echo unzip "$1"; echo unzip "$2"; 
  shift 2
done
1
ответ дан 17 March 2020 в 00:05

Циклично выполните сортированный массив версии с шагом два.

#!/bin/bash

eval \
"a=($(ls -v1 --quoting-style=shell-escape files/*))"

for ((i=0; i<${#a[@]}; i+=2)); do
    [[ -r ${a[$i]} ]] && \
        unzip "${a[$i]}"
    [[ -r ${a[(i+1)]} ]] && \
        unzip "${a[(i+1)]}"
done
1
ответ дан 17 March 2020 в 00:05

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

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