список файлов, пронумерованных в определенном диапазоне


16

У меня есть набор файлов в каталоге, пронумерованных следующим образом:

file1.txt
file2.txt
...
file30.txt
...

Теперь я хотел бы запустить команду для определенного диапазона файлов, скажем, с 18 по 31.

До сих пор я использовал следующие способы,

три аргумента

command file1[8-9].txt file2[0-9].txt file3[0-1].txt

Теперь предположим, что я хочу любой номер,

петля

for i in `jot - 18 31 2`; do echo file${i}.txt; done | xargs command

похоже, это более надежный цикл (пробелы работают)

for i in `jot - 18 31 2`; do echo "\"file${i}.txt\" "; done | xargs command

но кажется, что должен быть более простой способ сделать это. Я предполагаю, что лучшее решение - создать функцию bash, которая будет возвращать набор файлов в командную строку. Тогда я мог бы сделать что-то вроде,

command `filerange file 18 31`

Есть ли лучшие способы или предложения по эффективному выполнению этой задачи?

Я заранее прошу прощения, если я пропустил тот же вопрос, на который ответили где-то еще в Интернете или в сети superuser.


Я обновил свой вопрос, чтобы включить решение с использованием forцикла, который позволяет использовать пробелы в именах файлов с помощью xargs. Кажется, это работает, если у вас нет bash 4. Если у вас есть bash 4, то обязательно используйте расширение скобки! Смотрите выбранный ответ. Бесстыдная вилка для обновления Snow Leopard bash
milkypostman

Ответы:


25

Попробуй это:

for file in file{18..31}.txt

Он известен как «выражение последовательности» и является частью функции расширения скобок Bash . Работает в Баш 3 и 4.

Функция приращения является новой для Bash 4. Возможно, у вас есть Bash 3.x.

В Bash 4 вы можете сделать:

$ for i in {1..6..2}; do echo $i; done
1
3
5

Но в Bash 3 вы должны сделать это, чтобы получить те же результаты:

$ for ((i=1; i<=6; i+=2)); do echo $i; done

Та же форма увеличивается на единицу:

$ for ((i=1; i<=6; i++)); do echo $i; done

Любое число может быть переменной или выражением. Однако в выражении последовательности числа должны быть константами

Вот пример использования этой формы в ваших файлах:

for ((i=18; i<=31; i++))
do
    echo "file${i}.txt"
done

Еще одна новая особенность выражений последовательности в Bash 4 - возможность включать ведущие нули. Это полезно, если вы хотите создать (и использовать) пронумерованные файлы, которые можно правильно отсортировать.

В Bash 4:

touch file{001..010}.txt

создаст файлы с именами «file001.txt» - «file010.txt». Их имена будут отсортированы в ожидаемом порядке. Без начальных нулей файл «file10.txt» будет отсортирован перед «file1.txt».

Для работы с файлами вы можете использовать тот же синтаксис начального нуля:

for file in file{001..010}.txt; do echo "$file"; done

В Bash 3, если вам нужны начальные нули, вам нужно добавить значение самостоятельно:

for i in {1..10}
do
    printf -v i '%03d' $i 
    echo "file${i}.txt"
done

Оператор printfдобавляет к значению i начальные нули, поэтому ширина равна 3, например («4» становится «004»).

Редактировать:

Размещение пробелов в именах файлов просто:

$ touch "space name "{008..018..3}" more spaces"
$ ls -l sp*
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000008 more spaces
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000011 more spaces
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000014 more spaces
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000017 more spaces
$ for f in "space name "{008..018..3}" more spaces"; do mv "$f" "${f}.txt"; done
$ ls -l sp*
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000008 more spaces.txt
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000011 more spaces.txt
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000014 more spaces.txt
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000017 more spaces.txt

Спасибо! Я не знаю, где это было всю мою жизнь. Единственная вещь, которую я не могу заставить работать - это то, что приращение не работает в версии bash для OSX. то есть я не могу получить {1..10..2}работу в моем OSX Bash.
молочница

Ну, это потому, что Snow Leopard (по какой-то причине) использует bash 3.1. Это проблема программного обеспечения.
milkypostman

@milkypostman: функция приращения и начальные нули {01..10}являются новыми для Bash 4. Возможно, у вас есть Bash 3.x. Если вам нужна функция приращения или для использования переменных для границ диапазона, используйте эту форму: for ((i=1; i<=10; i+=2}(или i++для приращения на единицу). Любое число может быть переменной или выражением. Затем, чтобы использовать значение внутри forцикла: echo "file${i}.txt". In Bash 3, if you need leading zeros, inside the for loop do: printf -vi '% 03d' $ i`, который будет добавлять значение iс начальными нулями, например, с шириной 3, например ("4" становится "004").
Приостановлено до дальнейшего уведомления.

Деннис, есть ли способ обновить свое решение, чтобы включить альтернативную форму. Будучи комментарием, это немного запутывает то, что я, вероятно, должен получить.
молочница

@milkypostman: Смотрите мой отредактированный ответ.
Приостановлено до дальнейшего уведомления.
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.