Poniżej znajduje się pseudo-kod dla tego, co próbuję osiągnąć:
#!/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
Mogę wykonać to dobrze z wiersza poleceń, wstawiając rzeczywistą liczbę w sekwencji `{1..n} '. Muszę tylko wiedzieć, czy można tu dołączyć zmienną i jak to zrobić.
- Próbowałem
export
tego - Próbowałem umieścić samą zmienną w nawiasach klamrowych wewnątrz sekwencji:
{1..${numlines}}
- Próbowałem umieścić go w cudzysłowie, mając nadzieję, że rozwinie się:
{1.."$numlines"}
- Próbowałem uciec od
$
:{1..\$numlines}
Czy muszę używać set -[something]
polecenia, aby ta zmienna została rozwinięta? Próbowałem nawet niektórych form używania eval
... wszystko bezskutecznie.
Muszę tylko wiedzieć, czy brakuje mi czegoś prostego lub niejasnego, czy też jest to możliwe, zanim stracę na to więcej czasu.
Mógłbym opracować naprawdę bardzo hackerski sposób, aby działał zgodnie z potrzebami, ale chciałbym tego uniknąć, jeśli to w ogóle możliwe, i nauczyć się, jak to zrobić.
bash
shell-script
scripting
rubinorails
źródło
źródło
Odpowiedzi:
Niestety nie ma możliwości użycia zmiennej w tym rozwinięciu (AFAIK), ponieważ rozszerzenie zmiennej następuje po rozwinięciu nawiasu.
Na szczęście istnieje narzędzie, które wykonuje tę samą pracę.
seq
pochodzi z GNU coreutils; nie mam pojęcia, jak to zrobić w POSIX.źródło
seq
jest dobry dla systemów GNU i, jeśli dobrze pamiętam, najnowszego OSX. W innych systemach BSD można zamiast tego użyć jot .seq
działa świetnie. Dziękuję bardzo za szybką odpowiedź.{16..1}
?$(seq $numlines 1)
nie działał. Chyba zawsze mogęman seq
, ale zastanawiam się, czy ktokolwiek wiedział z góry.for i in $(seq $numlines -1 1)
seq ${numlines} -1 0
Pewnie. Jeśli potrzebujesz pętli for, która inkrementuje zmienną całkowitą, użyj formy
for
pętli, która inkrementuje zmienną całkowitą (lub, bardziej ogólnie, wykonuje arytmetykę na zmiennej (zmiennych) pętli).Ta konstrukcja działa w bash (i ksh93 i zsh), ale nie w zwykłym sh. W zwykłym sh użyj pętli while i konstrukcji test (
[ … ]
).źródło
Jeśli musisz unikać
seq
, co, jak wskazuje Tom Hunt, wydaje się być zwykłym rozwiązaniem tego problemu, toeval
zdecydowanie możesz to zrobić (choć nie zachęciłbym tego):Możesz pozostać POSIX, unikając rozszerzenia {}, i po prostu porównuj matematykę i liczbę całkowitą
$numlines
:Poza POSIX,
bash
aksh
azsh
także C-stylufor
pętle:źródło
seq
działał dobrze w moim scenariuszu i wydawał się najprostszym rozwiązaniem, dobrze jest wiedzieć, że istnieją inne (nawet POSIX) alternatywy. Dzięki za to.eval
; jeśli masz rozwinięcie nawiasu, masz pętlę w stylu C.eval
przykład był najprostszy i uratowałby mnie od konieczności szukania alternatywnego sposobu zrobienia tego przy użyciuseq
.while
Pętla jest nieco nieporęczne dla mnie. Lubię sprawić, by wszystko było krótkie i słodkie, i nigdy nie mogłem uruchomićfor
pętli w stylu C, podająci
wartość 0 lub 1. Nigdy nie powróciła poprawnie i zawsze była trochę zła. Jestem pewien, że można go poprawić, aby działał poprawnie, ale mimo to są to zdecydowanie pomocne rozwiązania.eval
Podejście jest problematyczne, jeśli nie ma nic nietrywialnym wewnątrz ciała pętli. Wyobrażam sobie, że nie byłoby bardzo czytelne, gdybyś potrzebował zagnieździć dwie takie pętle.