BASH: сортировка массива файлов с безумными именами - PullRequest
2 голосов
/ 05 августа 2011

Проблема:

Необходимо отсортировать массив, прежде чем работать с ним с помощью функции.

Сначала массив загружается с файлами:

unset a i
counter=1
while IFS= read -r -d $'\0' file; do
    a[i++]="$file"
done < <(find $DIR -type f -print0)

Далее каждый член массива отправляется в функцию

for f in "${a[@]}"
do
   func_hash "$f"
   [ $(expr $counter % 20) -eq 0 ] && printf "="
   counter=$((counter + 1))
done

Каким-то образом необходимо добавить сортировку в цикл for. Посмотрел через SO сообщения о сортировке массивов, но как-то мои сумасшедшие имена файлов вызывают проблемы, когда я пытаюсь использовать сортировку.

Идеи

Спасибо!

Bubnoff

ОБНОВЛЕНИЕ: Вот код с сортировкой:

while IFS= read -r -d $'\0' file; do
    func_hash "$file"
    [ $(expr $counter % 20) -eq 0 ] && printf "="
    counter=$((counter + 1))
done < <(find $DIR -type f -print0 | sort -z +1 -1)

Это сортировка по полному пути, а не по имени файла. Любые идеи о том, как сортировать по имени файла, учитывая, что путь необходим для функции?

ОБНОВЛЕНИЕ 2: Решено пойти на компромисс.

Моей главной целью было избежать временных файлов с помощью сортировки. GNU sort может написать обратно в оригинал файл с параметром -o, так что теперь я могу:

sort -o $OUT -t',' -k 1 $OUT

У любого есть более «элегантное» решение (что бы это ни значило).

решено См. Ответ jw013 ниже. Спасибо мужчина!

1 Ответ

2 голосов
/ 06 августа 2011

EDIT

while IFS= read -r -d/ && read -r -d '' file; do
    a[i++]="$file"
done < <(find "$DIR" -type f -printf '%f/%p\0' | sort -z -t/ -k1 )

Обоснование:

  • Я предполагаю, что / никогда не является допустимым символом в имени файла (что представляется разумным для большинства * файловых систем nix, так как это разделитель пути).
  • -printf используется для печати имени файла без начальных каталогов, затем полного имени файла с путем, разделенным /. Сортировка происходит в первом поле, отделенном /, которое должно быть полным именем файла без пути.
  • read модифицируется для первого использования / в качестве разделителя для исключения имени файла без пути.

примечание

Любая оболочка POSIX должна поддерживать оператор по модулю как часть своего арифметического расширения. Вы можете заменить строку вызовом внешней команды expr во втором цикле на

[ $(( counter % 20 )) -eq 0 ] ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...