Nowe posty

Autor Wątek: Petla for po wszytkich plikach w danym folderze  (Przeczytany 13707 razy)

wiatrak

  • Gość
Petla for po wszytkich plikach w danym folderze
« dnia: 2013-10-10, 10:08:16 »
Witam,

Jestem begginer w bash i linux. Napisalam maly skrypt do automatyzacji procesu obliczania Calculate.
Mam w folderze pts1 pliki : od 00.pts, 10.pts , ..., 90.pts.
Potrzebuje aby petla for przeszla przez wyszystkie pliki od 00 do 90.
Napisalam to w ponizszy sposob i dziala ok ale  chcialabym zapytac o bardziej optymalne rowziazanie tego problemu ?
Nie ma moze w bash jakiegos innego polecenia zamiast
"for i in 0 1 2 3 4 5 6 7 8 9; " ?

ref_phase='pts1/60.pts'
pts1_dir='pts1'
midp_popi1='midp1'
mkdir out
mkdir log

for i in 0 1 2 3 4 5 6 7 8 9;
do
#echo $i
#Calculate --ref $ref_phase -i $pts_dir/$i0.pts --vf midp/vf_midp_$i0.mhd --general out1/TRE_$i0.txt > out1/tre_log_$i0.txt 2>&1 --verbose
echo $i
if [ $i == 0 ];
then
Calculate  --ref $ref_phase -i $pts1_dir/00.pts --vf $midp_popi1/vf_midp_00.mhd --general out/TRE_00.txt > log/tre_log1_00.txt 2>&1 --verbose
elif [ $i != 0 ];
then  
j=$(($i * 10))
echo $j
Calculate --ref $ref_phase -i $pts1_dir/$j.pts --vf $midp_popi1/vf_midp_$j.mhd --general out/TRE_$j.txt > log/tre_log1_$j.txt 2>&1 --verbose
fi
done


Bede wdzieczna za kazda pomoc prosze.

Offline roobal

  • Users
  • Guru
  • *****
  • Wiadomości: 2056
    • Zobacz profil
Petla for po wszytkich plikach w danym folderze
« Odpowiedź #1 dnia: 2013-10-10, 10:25:43 »
Cytat: wiatrak
Nie ma moze w bash jakiegos innego polecenia zamiast
"for i in 0 1 2 3 4 5 6 7 8 9; " ?
Ano jest, są nawet dwa.

1. for ((i=0; $i<=9; i++))
2. for i in $(seq 0 9)

alvaro

  • Gość
Petla for po wszytkich plikach w danym folderze
« Odpowiedź #2 dnia: 2013-10-10, 10:33:36 »
Możesz spróbować czegoś takiego:
for i in {00..90}; do echo "$i"; done
Zmienna sterująca będzie przyjmować wartości od 00 do 90:
$ for i in {00..90}; do echo "$i"; done | head -n 5
00
01
02
03
04
$ for i in {00..90}; do echo "$i"; done | tail -n 5
86
87
88
89
90
Jeśli kiedyś będziesz potrzebować, żeby zmienna zwiększała się o inną wartość niż jeden przy każdej iteracji możesz użyć następującej składni:
for i in {00..90..2}; do echo "$i"; done
W powyższym przypadku z każdym krokiem pętli zmienna będzie zwiększała się o dwa a więc zostaną wypisane tylko liczby parzyste od 00 do 90.

wiatrak

  • Gość
Petla for po wszytkich plikach w danym folderze
« Odpowiedź #3 dnia: 2013-10-10, 10:55:35 »
Dzieki wielkie za bardzo przydatne wskazowki i przyklady ! Thanks :)

xavery

  • Gość
Petla for po wszytkich plikach w danym folderze
« Odpowiedź #4 dnia: 2013-10-10, 13:59:58 »
Cytat: alvaro
for i in {00..90..2}; do echo "$i"; done
Tylko, że to chodzi tylko w bash i chyba tylko w wersji >4. Ja jednak preferuję przenośne rozwiązania i w związku z tym polecam seq:)

Offline ultr

  • Users
  • Guru
  • *****
  • Wiadomości: 1177
    • Zobacz profil
Petla for po wszytkich plikach w danym folderze
« Odpowiedź #5 dnia: 2013-10-10, 21:19:01 »
Co do tematu wątku:

> Petla for po wszytkich plikach w danym folderze

for plik in *; do
  echo "$plik"
done
find ./ -type f -exec echo {} ';'
while read plik; do
  echo "$plik"
done < <( find ./ -type f )

darkdancer

  • Gość
Petla for po wszytkich plikach w danym folderze
« Odpowiedź #6 dnia: 2013-10-11, 13:41:56 »
Cytat: xavery
Ja jednak preferuję przenośne rozwiązania i w związku z tym polecam seq:)
seq niestety nie jest dostępne w części unixów, przykład Solaris albo FreeBSD :-(

xavery

  • Gość
Petla for po wszytkich plikach w danym folderze
« Odpowiedź #7 dnia: 2013-10-16, 14:55:55 »
Cytat: darkdancer
seq niestety nie jest dostępne w części unixów, przykład Solaris albo FreeBSD :-(
Co prawda rzadko mam okazję używać FreeBSD a jeszcze rzadziej Solarisa ale we FreeBSD seq jak najbardziej (już) jest. man seq:

HISTORY
     The seq command first appeared in Plan 9 from Bell Labs.  A seq command
     appeared in NetBSD 3.0, and ported to FreeBSD 9.0.
I tak to jest z tą przenośnością - nie można na niej do końca polegać:) Zawsze  można użyć bardziej pierwotnych narzędzi jak:

perl -e 'printf "%.2d ",$_ for 0..9;'
Bo Perl to już chyba raczej wszędzie jest:)

alvaro

  • Gość
Petla for po wszytkich plikach w danym folderze
« Odpowiedź #8 dnia: 2013-10-18, 07:28:56 »
Cytat: xavery
Cytat: alvaro
for i in {00..90..2}; do echo "$i"; done
Tylko, że to chodzi tylko w bash i chyba tylko w wersji >4. Ja jednak preferuję przenośne rozwiązania i w związku z tym polecam seq:)
W pytaniu wyraźnie była mowa o systemie Linux i powłoce bash.
Tak się składa, że wiodące dystrybucje systemu Linux mają powłokę bash w wersji czwartej już od dłuższego czasu.
EL6: bash 4.1
Debian 6: bash 4.1
Debian 7: bash 4.2
Ubuntu 10.04 LTS: bash 4.1
Ubuntu 12.04 LTS: bash 4.2

Poza tym seq wcale nie jest tutaj dobrym przykładem na przenośność.
W systemie FreeBSD pojawił się dopiero w wersji 9.0 (2012.01.12) podczas gdy bash 4.x był już w wersji 7.2 (2009.05.04).
W starszych wersjach Mac OS X (np. 10.4 Tiger) też go nie uświadczymy.
W innych systemach Unix/Unix-like/zgodnych z POSIX może to również stanowić problem.

Skoro jednak już rozważamy najprzeróżniejsze warianty to z wykorzystaniem seq mogłoby to wyglądać tak:
seq -w 0 90
for i in $(seq -w 0 90); do echo "Zrob cos z ${i}."; done
Pod starszymi systemami FreeBSD/Mac OS X można zamiast seq użyć jot:
jot -w "%.2d " 91 0 90
for i in $(jot -w "%.2d " 91 0 90); do echo "Zrob cos z ${i}."; done
Zamiast powłoki bash można także użyć zsh:
zsh -c 'for i in {00..90}; do echo "Zrob cos z ${i}."; done'
Jeszcze inne pomysły:
for ((i=0; i<=90; i++)); do j=$(printf "%.2d" "$i"); echo "Zrob cos z ${j}."; done
for i in $(awk 'BEGIN { for (i=0; i<=90; i++) { printf "%.2d ", i } }'); do echo "Zrob cos z ${i}."; done