Ниже приведен некоторый псевдокод для того, что я пытаюсь выполнить:
#!/bin/bash
# I already have the variable below figured out (positive integer):
numlines=$([returns number of lines containing specific characters in a file])
# This is basically what I want to do with it:
for i in {1..$numlines}; do
# the part below is already figured out as well:
do some other stuff
done
Я могу выполнить его из командной строки, вставив фактическое число в последовательность `{1..n} '. Мне просто нужно знать, можно ли сюда включить переменную и как это сделать.
- Я попробовал
export
это - Я попытался поместить саму переменную в фигурные скобки внутри последовательности:
{1..${numlines}}
- Я попытался поместить это в двойные кавычки, надеясь, что это расширится:
{1.."$numlines"}
- Я пытался избежать
$
:{1..\$numlines}
Нужно ли использовать set -[something]
команду для расширения этой переменной? Я даже попробовал некоторые формы использования eval
... все безрезультатно.
Мне просто нужно знать, есть ли что-то простое или неясное, что я пропускаю, или это вообще возможно, прежде чем я потрачу на это больше времени.
Я мог бы создать действительно очень по- хакерский способ сделать это так, чтобы он работал по мере необходимости, но я бы хотел этого избежать, если это вообще возможно, и научиться правильно делать это.
bash
shell-script
scripting
rubynorails
источник
источник
Ответы:
К сожалению, нет никакой возможности использовать переменную в этом расширении (AFAIK), так как расширение переменной происходит после расширения скобки.
К счастью, есть инструмент, который выполняет ту же работу.
seq
из GNU coreutils; понятия не имею, как это сделать в POSIX.источник
seq
хорошо для систем GNU и, если я правильно помню, самый последний OSX. В других системах BSD вместо этого можно использовать jot .seq
работает отлично. Большое спасибо за ваш быстрый ответ.{16..1}
?$(seq $numlines 1)
не сработало. Я думаю, что могу всегдаman seq
, но просто интересно, если бы кто-нибудь знал с макушкой.for i in $(seq $numlines -1 1)
seq ${numlines} -1 0
Конечно. Если вам нужен цикл for, который увеличивает целочисленную переменную, используйте форму
for
цикла, которая увеличивает целочисленную переменную (или, в более общем случае, выполняет арифметику для переменной (переменных) цикла).Эта конструкция работает в bash (и ksh93 и zsh), но не в обычном sh. В обычном sh используйте цикл while и конструкцию test (
[ … ]
).источник
Если вы должны избегать
seq
, что, как указывает Том Хант, кажется, является обычным решением этой проблемы, тогдаeval
определенно можно сделать это (хотя я бы не поощрял это):Вы можете остаться в POSIX, избежав раскрытия {}, и просто выполните математические и целочисленные сравнения
$numlines
:Вне POSIX,
bash
аksh
иzsh
также имеет C-стильfor
петля:источник
seq
отлично работал для моего сценария и казался самым простым решением, полезно знать, что есть и другие (даже POSIX) альтернативы. Спасибо за это.eval
; если у вас есть расширение скобки, у вас есть цикл в стиле C.eval
пример был самым простым и избавил меня от необходимости искать альтернативный способ сделать это, используяseq
.while
Петля немного громоздким для меня. Мне нравится, чтобы все было коротким и приятным, и я никогда не мог заставитьfor
цикл в стиле C работать, даваяi
значение 0 или 1. Он никогда не возвращался правильно и всегда был немного не в порядке. Я уверен, что он может быть настроен для правильной работы, но это определенно полезные решения, тем не менее.eval
Подход является проблематичным , если есть что - нибудь нетривиальные внутри тела цикла. Я полагаю, что было бы не очень читабельным, если бы вам нужно было вложить два таких цикла.