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


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.