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 .

1 ответ1

23

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

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .