Portál AbcLinuxu, 24. dubna 2024 14:00


Dotaz: for a dvě pole

11.1.2011 01:01 jsk | skóre: 10
for a dvě pole
Přečteno: 352×
Odpovědět | Admin

Dobrý den,

potřeboval bych poradit jak zjednodušit násl. úlohu tak, aby pro každou hodnotu z dvojice $prvni a $druhy nemusel vypisovat vlastní for pro všechny indexy.

prvni=(`cat soubor1`)
druhy=(`cat soubor2`)
for ikx in $( seq ${prvni[0]} )
do 'třeba wget' "${ikx}${druhy[0]}"
done

$prvni a $druhy mají stejný počet hodnot, $prvni je cele kladné číslo a $druhy je text.

Měl jsem dojem, že by šlo využít toho, že hodnoty indexu jsou pro jednotlivé cykly for stejné, ale to mi přišlo jako speciální případ a zatím ani nevím jak na to.

S načítanými soubory (soubor1 a soubor2) mohu volně manipulovat a případně je přizpůsobit.

Předem všem děkuji!

jsk

Nástroje: Začni sledovat (1) ?Zašle upozornění na váš email při vložení nového komentáře.

Odpovědi

11.1.2011 08:33 Šangala | skóre: 56 | blog: Dutá Vrba - Wally
Rozbalit Rozbalit vše Re: for a dvě pole
Odpovědět | | Sbalit | Link | Blokovat | Admin
Pomůže toto:?
#!/bin/bash
#vstup
IN1="kuk baf bum"
IN2="KUK BAF BUM"

#priprava pole
saveIFS=$IFS
IFS=" "
ARR1=( $IN1 )
ARR2=( $IN2 )
IFS=$saveIFS

#pocet prvku
CNT=${#ARR1[&]}

#kontrola prvku v obou polich
if [ ${CNT} -ne ${#ARR2[&]} ]; then
  echo "Error: cnt1 != cnt2"
  exit 3
fi

#zpracovani
for (( i=0; i<${CNT}; i++ )); do
  echo "${ARR1[$i]} - ${ARR2[$i]} "
done

exit 0
Pro oddělovač řádků místo mezery:
IFS="
"
To, že trpíš stihomamem, ještě neznamená, že po tobě nejdou. ⰞⰏⰉⰓⰀⰜⰉ ⰗⰞⰅⰜⰘ ⰈⰅⰏⰉ ⰒⰑⰎⰉⰁⰕⰅ ⰏⰉ ⰒⰓⰄⰅⰎ ·:⁖⁘⁙†
David Watzke avatar 11.1.2011 08:47 David Watzke | skóre: 74 | blog: Blog... | Praha
Rozbalit Rozbalit vše Re: for a dvě pole
Počet prvků je takhle:
${#ARR1[*]}
nebo případně
${#ARR1[@]}
“Being honest may not get you a lot of friends but it’ll always get you the right ones” ―John Lennon
11.1.2011 10:35 Šangala | skóre: 56 | blog: Dutá Vrba - Wally
Rozbalit Rozbalit vše Re: for a dvě pole
Sorry, to byla chyba při záměně za HTML entity (proč jsem vyměnil @ za &amp;, nevím) :(
Oprava:
#!/bin/bash
#vstup
IN1="kuk baf bum"
IN2="KUK BAF BUM"

#priprava pole
saveIFS=$IFS
IFS=" "
ARR1=( $IN1 )
ARR2=( $IN2 )
IFS=$saveIFS

#pocet prvku
CNT=${#ARR1[@]}

#kontrola prvku v obou polich
if [ ${CNT} -ne ${#ARR2[@]} ]; then
  echo "Error: cnt1 != cnt2"
  exit 3
fi

#zpracovani
for (( i=0; i<${CNT}; i++ )); do
  echo "${ARR1[$i]} - ${ARR2[$i]} "
done

exit 0
To, že trpíš stihomamem, ještě neznamená, že po tobě nejdou. ⰞⰏⰉⰓⰀⰜⰉ ⰗⰞⰅⰜⰘ ⰈⰅⰏⰉ ⰒⰑⰎⰉⰁⰕⰅ ⰏⰉ ⰒⰓⰄⰅⰎ ·:⁖⁘⁙†
11.1.2011 11:09 Patrik Uhrak | skóre: 31 | blog: pato
Rozbalit Rozbalit vše Re: for a dvě pole
Odpovědět | | Sbalit | Link | Blokovat | Admin

Zdravim,

ja tu mam tiez jedno riesenie a ci idealne, tak to zalezi na okolnostiach:

 

#! /bin/bash

mapfile -t PRVNI <./soubor1
mapfile -t DRUHY <./soubor2

while [[ -n "${PRVNI[0]}" && ${#PRVNI[@]} -eq ${#DRUHY[@]} ]]
do
echo "Aktualna dvojica: ${PRVNI[0]} - ${DRUHY[0]}"
unset PRVNI[0]
PRVNI=( ${PRVNI[@]} )
unset DRUHY[0]
DRUHY=( ${DRUHY[@]} )
done

Vyhody: Aj napriek nerovnakemu poctu clenov v jednom ci druhom subore,f popari, co sa da a az ked nenajde dvojicu, skonci. Co je zaroven jediny mozny koniec.

Nevyhody: Polia budu na konci cyklu prazdne a teda pri voli dalsieho pouzitia by bolo znova nutne nacitat zo suboru (velmi zle :)) . Toto sa da obist za cenu vytvorenia docasnych poli.  Pre kazde jedno povodne vytvorit jedno docasne priamo vo funkcii. Pole bude platne len v ramci funkcie.                     PRVNI_TMP=(  ${PRVNI[@]} )

#! /bin/bash

Prirad()
{
declare -a PRVNI_TMP=( ${PRVNI[@]} )
declare -a DRUHY_TMP=( ${DRUHY[@]} )

while [[ -n "${PRVNI_TMP[0]}" && ${#PRVNI_TMP[@]} -eq ${#DRUHY_TMP[@]} ]]
do
echo "Aktualna dvojica: ${PRVNI_TMP[0]} - ${DRUHY_TMP[0]}"
unset PRVNI_TMP[0]
PRVNI_TMP=( ${PRVNI_TMP[@]} )
unset DRUHY_TMP[0]
DRUHY_TMP=( ${DRUHY_TMP[@]} )
done
}

mapfile -t PRVNI <./soubor1
mapfile -t DRUHY <./soubor2
Prirad

Nevravim, ze idealne, ale riesenie to je.


            
11.1.2011 12:13 Patrik Uhrak | skóre: 31 | blog: pato
Rozbalit Rozbalit vše Re: for a dvě pole

Oprava:

Cyklus ma byt nasledovne:

while [[ -n "${PRVNI[0]}" && -n "${DRUHY[0]}" ]]

aby to malo tu mnou spominanu "vyhodu". Je nutne vediet, ci tie dva prvky z prveho a druheho pola maju nejaku spojitost (meno a priezvisko a pod.).

12.1.2011 06:14 jsk | skóre: 10
Rozbalit Rozbalit vše Re: for a dvě pole

Zdravím,
pokusím se vysvětlit souvislost prvků mám-li např.
S1=(1 2 3 4 7 8 9 10 11)
a
S2=(100 83 150 230 11 18 22 55 99)
pro S1[0] se provede činnost 100×

Asi jsem to původně popsal dost neobratně :-(

jsk

12.1.2011 08:19 Šangala | skóre: 56 | blog: Dutá Vrba - Wally
Rozbalit Rozbalit vše Re: for a dvě pole
Učím se rozumět řeči tvého kmene, dává toto co je třeba? :):
#!/bin/bash
#vstup
IN1="kuk baf bum klof nic nic2"
IN2="3 1 7 2 pepa"

#priprava pole
saveIFS=$IFS
IFS=" "
ARR1=( $IN1 )
ARR2=( $IN2 )
IFS=$saveIFS

#pocet prvku
CNT1=${#ARR1[@]}
CNT2=${#ARR2[@]}
if [ ${CNT2} -lt ${CNT1} ]; then
  MAX=${CNT2}
else
  MAX=${CNT1}
fi

#zpracovani
for (( i=0; i<${MAX}; i++ )); do
  NUM_MAX=$(( ${ARR2[$i]} + 0 ))
  for  (( j=0; j<${NUM_MAX}; j++ )); do
    echo "${ARR1[$i]} - $(($j+1))"
  done
done

exit 0

To, že trpíš stihomamem, ještě neznamená, že po tobě nejdou. ⰞⰏⰉⰓⰀⰜⰉ ⰗⰞⰅⰜⰘ ⰈⰅⰏⰉ ⰒⰑⰎⰉⰁⰕⰅ ⰏⰉ ⰒⰓⰄⰅⰎ ·:⁖⁘⁙†
David Watzke avatar 11.1.2011 20:14 David Watzke | skóre: 74 | blog: Blog... | Praha
Rozbalit Rozbalit vše Re: for a dvě pole
To s tím unsetem je to slušná chlívárna, radši použij for a nic "neunsetuj".
“Being honest may not get you a lot of friends but it’ll always get you the right ones” ―John Lennon
11.1.2011 23:30 Patrik Uhrak | skóre: 31 | blog: pato
Rozbalit Rozbalit vše Re: for a dvě pole

Tiez si myslim. ;(

11.1.2011 22:05 jsk | skóre: 10
Rozbalit Rozbalit vše Re: for a dvě pole
Odpovědět | | Sbalit | Link | Blokovat | Admin

Zdravím a děkuji všem,

nejsem si zcela jistý, že jsem problém správně popsal, pro hodnotu na pozici v $soubor1 potřebuji, aby proběhlo zpracování pro všechny hodnoty v rozsahu od 1 až po hodnotu stejné pozice v soubor2, takže na jeden průchod prvním for potřebuji více průchodů ve druhém for. Měl jsem na mysli jako něco viz. níže, ale to mi nepokryje v druhém cyklu všechny případy, prostě mi to nepodrží zet. 20 = počet řádků.

prvni=(`cat soubor1`)
druhy=(`cat soubor2`)

then for zet in ( 1 2 ... 20} )
do for ikx in $( seq ${prvni[$zet]} ) ; do 'třeba wget' "neco${ikx}a_neco_jineho${druhy[$zet]}" ; done
done

Dostal jsem se k domácímu kompu teprve teď, takže jsem se možná ne všechny hned reakce pochopil správně, používám BASH nárazově a moc toho zatím neumím.

jsk

11.1.2011 22:39 Šangala | skóre: 56 | blog: Dutá Vrba - Wally
Rozbalit Rozbalit vše Re: for a dvě pole
Nemluvím [plně řečí tvého kmene, ale pomůže?:
#!/bin/bash
#vstup
IN1="kuk baf bum bac snup nic"
IN2="KUK BAF BUM BAC SNUP"

#priprava pole
saveIFS=$IFS
IFS=" "
ARR1=( $IN1 )
ARR2=( $IN2 )
IFS=$saveIFS

#pocet prvku
CNT1=${#ARR1[@]}
CNT2=${#ARR2[@]}

#zpracovani
for (( i=0; i<${CNT1}; i++ )); do
  if [ $i -lt ${CNT2} ]; then
    for  (( j=0; jlt;=i; j++ )); do
      echo "${ARR1[$i]} - ${ARR2[$j]}"
    done
  fi
done

exit 0

To, že trpíš stihomamem, ještě neznamená, že po tobě nejdou. ⰞⰏⰉⰓⰀⰜⰉ ⰗⰞⰅⰜⰘ ⰈⰅⰏⰉ ⰒⰑⰎⰉⰁⰕⰅ ⰏⰉ ⰒⰓⰄⰅⰎ ·:⁖⁘⁙†
11.1.2011 23:12 jsk | skóre: 10
Rozbalit Rozbalit vše Re: for a dvě pole

Díky,
asi to není úplně snadné porozumět tomu co jsem napsal :(, snažil jsem se to popsat obecně, abych se nedobral k řešení postaveném na něčem zcela specifickém a mimochodem jsem to v pův. zadání napsal špatně, na vstupu jsou čísla.
Nerozumím úplně řádkům 19 a 20 hlavně -lt a jlt;=i mi není jasné, IFS jsem zřejmě již pochopil, ale vypadá to, že je to ono, pro každé i se provede j průchodů a i i j mohu vložit jako proměnou do url které dávám wget-u, zde echo.

Konkrétní test provedu až zítra, teď už musím končit, ještě jednou děkuji!!

Zdraví jsk

11.1.2011 23:44 Šangala | skóre: 56 | blog: Dutá Vrba - Wally
Rozbalit Rozbalit vše Re: for a dvě pole
if [ $i -lt ${CNT2} ]; then
  #dělej toto pokud $i je menší (l-ower t-hen) než $CNT
  #viz man test
fi
No k 20tému řádku, nevím jak to dneska dělám ale již podruhé v této diskuzi při záměně znaků za html entity to nějak sprasím.
Oprava:
#!/bin/bash
#vstup
IN1="kuk baf bum bac snup nic"
IN2="KUK BAF BUM BAC SNUP"
 
#priprava pole
saveIFS=$IFS
IFS=" "
ARR1=( $IN1 )
ARR2=( $IN2 )
IFS=$saveIFS
 
#pocet prvku
CNT1=${#ARR1[@]}
CNT2=${#ARR2[@]}
 
#zpracovani
for (( i=0; i<${CNT1}; i++ )); do
  if [ $i -lt ${CNT2} ]; then
    for  (( j=0; j<=$i; j++ )); do
      echo "${ARR1[$i]} - ${ARR2[$j]}"
    done
  fi
done
 
exit 0
Vlastni for může být realizovan i takto, přijde na to co se má stát když nemají pole stejný počet prvků.
#zpracovani
for (( i=0; i<${CNT1}; i++ )); do
  if [ $i -lt ${CNT2} ]; then
    k=$i
  else
    k=$((${CNT2} - 1))
  fi
  for  (( j=0; j<=$k; j++ )); do
    echo "${ARR1[$i]} - ${ARR2[$j]}"
  done
done
To, že trpíš stihomamem, ještě neznamená, že po tobě nejdou. ⰞⰏⰉⰓⰀⰜⰉ ⰗⰞⰅⰜⰘ ⰈⰅⰏⰉ ⰒⰑⰎⰉⰁⰕⰅ ⰏⰉ ⰒⰓⰄⰅⰎ ·:⁖⁘⁙†
11.1.2011 23:45 Patrik Uhrak | skóre: 31 | blog: pato
Rozbalit Rozbalit vše Re: for a dvě pole

Zdravim,

19. riadok : -lt , -gt , -le, -ge, -ne, -eq  : su pre porovnavanie celociselnych hodnot (integer)

20. riadok : Tam je preklep, spravne by mal byt takto zrejme:  for  (( j=0; j<=${i}; j++ )); do

Založit nové vláknoNahoru

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.