Portál AbcLinuxu, 8. května 2025 06:07
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
#!/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 0Pro oddělovač řádků místo mezery:
IFS=" "
${#ARR1[*]}nebo případně
${#ARR1[@]}
#!/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
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.
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.).
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
#!/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
Tiez si myslim. ;(
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
#!/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
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
if [ $i -lt ${CNT2} ]; then #dělej toto pokud $i je menší (l-ower t-hen) než $CNT #viz man test fiNo 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.
#!/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 0Vlastni 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
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
Tiskni
Sdílej:
ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.