Как я могу перечислить диапазон файлов в сценарии Bash?

У меня есть несколько файлов в папке со следующими именами:

FILE_201.txt
FILE_206.txt
FILE_215.txt
FILE_223.txt
FILE_229.txt
FILE_232.txt

Я хочу выбрать файлы между двумя значениями (например, между «210» и «230»). Из командной строки запустив

ls -1 FILE_{210..230}.txt

перечисляет нужные файлы; нет проблем. Однако, если я запускаю следующий сценарий Bash,

#!/bin/bash
ls -1 FILE_{$1..$2}.txt

передавая ему 210 и 230 в качестве аргументов, это не работает.

Что я делаю не так?


person urgeo    schedule 12.03.2015    source источник


Ответы (2)


Проблема не в запуске команды из командной строки или из скрипта. Вы можете убедиться в этом сами, выполнив в командной строке следующее:

$ set 210 230 # assigns variables $1 and $2 the values "210" and "230", resp.
$ ls -1 FILE_{$1..$2}.txt
ls: FILE_{210..230}.txt: No such file or directory

Как видите, вы получаете ту же ошибку, что и в файле скрипта. Проблема в том, что раскрытие скобок происходит перед раскрытием переменной.

В этом случае к тому времени, когда $1 и $2 расширятся до 210 и 230, уже слишком поздно интерпретировать диапазон как таковой; часть { .. } просто остается без какого-либо особого смысла.

В любом случае, использование здесь ls — плохая идея, потому что вы получите сообщение об ошибке для каждого имени файла в диапазоне, который не соответствует существующему файлу. Лучше использовать комбинацию цикла for и seq, как в этом ответе:

#!/bin/bash

# test.sh

for n in $(seq $1 $2); do 
    f="FILE_$n.txt"
    if [ -e $f ]; then
        printf $s\\n "$f"
    fi
done

Пример:

$ touch FILE_209.txt
$ touch FILE_213.txt
$ touch FILE_224.txt
$ touch FILE_232.txt
$ bash test.sh 210 230
FILE_213.txt
FILE_224.txt
person jub0bs    schedule 12.03.2015
comment
Ваш ответ в stackoverflow.com/q/29007821/1983854 был совершенно хорош, только другой помог мне лучше. Пожалуйста, рассмотрите возможность его восстановления, так как это повышает ценность всего вопроса! - person fedorqui 'SO stop harming'; 12.03.2015
comment
@fedorqui Спасибо, но я понял одну проблему с этим: если по какой-то причине вы хотите извлечь все файлы из коммита, кроме текущего, git reset --hard <commit> сбросит вашу текущую ветку на <commit> , тогда как git checkout -- . poke не будет. - person jub0bs; 12.03.2015

В случае, если кто-то заинтересован, вам нужно «оценить» вашу линию. то есть

eval "ls FILE_{$1..$2}.txt
person Lungang Fang    schedule 12.03.2015