Автор Тема: bash - Принтване на 2 променливи от масив при цикъл  (Прочетена 1462 пъти)

PhrozenCrew

  • Напреднали
  • *****
  • Публикации: 51
    • Профил
Здравейте,

Опитвам се да направя простичка текстова база данни, но нещо не мога да се сетя как да изкам втори или трети елемент от масива. Ето примера:
файл дб - users.txt
Ime1:Vor name 1:addres 1
Ime2:Vor name 2:addres 2
Ime3:Vor name 3:addres 3
Ime4:Vor name 4:addres 4

Кода с който изваждам имената

USERS=users.txt
n=1

for name in $(awk 'BEGIN{FS=":"}{print $1}' < "$USERS" )
do
  echo "USER $n = $name"
  let "n += 1"
done

Желаниеето ми е на този ред:
echo "USER $n = $name"
да мога да добавя $addres.
Предварително благодаря за всяка идея!
Активен

ntrance

  • Напреднали
  • *****
  • Публикации: 696
    • Профил
Нещо не мога да го разбера това , я дай един пример от това по горе  какъв искаш да ти бъде резулатата .
Активен

radoulov

  • Напреднали
  • *****
  • Публикации: 116
    • Профил
Код:
j=0

while IFS=: read n sn a; do
  printf 'user %d = %s, address = %s\n' \
    $((++j)) "$n" "$a"
done < users.txt
   

$((++j)) изисква bash >= 3 ако не се лъжа.
Ако ти дава грешка можеш да използваш:

Код:
$((j+=1))
Активен

neter

  • Global Moderator
  • Напреднали
  • *****
  • Публикации: 3408
  • Distribution: Debian, SailfishOS, CentOS
  • Window Manager: LXDE, Lipstick
    • Профил
    • WWW
Друго решение е с 'cut'. Ако във for цикъла на променливата $name задаваме стойност целият ред, то можем да получим това
Код
GeSHi (Bash):
  1. name='Ime1:Vor name 1:addres 1'
  2. edno=`echo $name | cut -d':' -f1`
  3. dve=`echo $name | cut -d':' -f2`
  4. tri=`echo $name | cut -d':' -f3`
На променливите $edno, $dve и $tri ще се присвоят стойности съответно "Ime1", "Vor name 1" и "address 1" ;)
Активен

"Да си добре приспособен към болно общество не е признак за добро здраве" - Джиду Кришнамурти

PhrozenCrew

  • Напреднали
  • *****
  • Публикации: 51
    • Профил
Код:
j=0

while IFS=: read n sn a; do
  printf 'user %d = %s, address = %s\n' \
    $((++j)) "$n" "$a"
done < users.txt
   

$((++j)) изисква bash >= 3 ако не се лъжа.
Ако ти дава грешка можеш да използваш:

Код:
$((j+=1))
Много интересен код! Благодаря ти, radoulov!
Версията ми е 3.2-1 и всичко е ОК. Помислих си да ползвам IFS, обаче нямам достатъчно опит.
Може ли да попитам нещо за цикъла while:
while IFS=: read n sn a
на това отговарят %d, %s и %s в същата последователност, нали?
Ако е така, значи научих още нещо за баш :)
Сега ще пробвам и с cut.
Благодаря ви пичове!
Активен

radoulov

  • Напреднали
  • *****
  • Публикации: 116
    • Профил
Цитат
[...]Може ли да попитам нещо за цикъла while:
while IFS=: read n sn a
на това отговарят %d, %s и %s в същата последователност, нали?

Ако разбирам правилно въпроса - не: %d форматира и извежда променливата j,
а sn в случая не се извежда от printf.





Активен

PhrozenCrew

  • Напреднали
  • *****
  • Публикации: 51
    • Профил
Вярно! Ами sn тогава какво прави?
Извинявам се за глупавите въпроси, но не можах сам да намеря логиката.

ПСМ Ето и един много лаишки код с cut:
oldIFS=${IFS} # Zapazvane na tekushtia separator
IFS=$'\n' # nov separator za krai na liniata
for line in $(cat users.txt); do
   echo "USER: "$(echo $line | cut -d":" -f1)"   ADDRES: "$(echo $line | cut -d":" -f3);
done
IFS=${oldIFS} # vrystame defoltnia separator
--
Странно ми е, че ако ползвам:
while read line; do echo $line; done <users.txt
ми се губи един ред - последният?! Ако и това някой успее да ми го обясни работата отива към черпушка :)
« Последна редакция: Nov 16, 2009, 13:57 от PhrozenCrew »
Активен

radoulov

  • Напреднали
  • *****
  • Публикации: 116
    • Профил
Цитат
Вярно! Ами sn тогава какво прави?
Извинявам се за глупавите въпроси, но не можах сам да намеря логиката.

Позволява да достигнеш до данните за address.
Може би така ще е по-ясно:

Код:
zsh-4.3.10[t]% while IFS=: read n sn a; do
  printf 'n is |%s|, sn is |%s|, a is |%s|\n' \
  "$n" "$sn" "$a"
done < users.txt 
n is |Ime1|, sn is |Vor name 1|, a is |addres 1|
n is |Ime2|, sn is |Vor name 2|, a is |addres 2|
n is |Ime3|, sn is |Vor name 3|, a is |addres 3|
n is |Ime4|, sn is |Vor name 4|, a is |addres 4|
Активен

radoulov

  • Напреднали
  • *****
  • Публикации: 116
    • Профил
Цитат
Странно ми е, че ако ползвам:
while read line; do echo $line; done <users.txt
ми се губи един ред - последният?![...]

Пробвй да конвертираш фила с dos2unix :)
Активен

PhrozenCrew

  • Напреднали
  • *****
  • Публикации: 51
    • Профил
Еее-е-е, браво! Задаваш си списък с променливите. Супер полезно ми е това, което си написал!
Значи мога да използвам тази възможност както например в perl или php:
list($n, $sn, $a) = preg_split(/:/,$line)
...

Пробвах с dos2unix, но явно средата, до която имам достъп в момента не може да работи киоректно. Бачкам със CygWin под WinXPSP3. А и версията ми е старичка. Довечера в къщи ще пробвам пак.

Благодаря отново!
Активен

Подобни теми
Заглавие Започната от Отговора Прегледи Последна публикация
Bash-подаване на сигнали м/у процеси
Общ форум
bonbon 2 8171 Последна публикация Dec 23, 2006, 21:56
от lnxman
Изпълнение на bash скрипт по дадено време
Настройка на програми
xtakedownedx 4 8920 Последна публикация Apr 18, 2007, 16:44
от Hapkoc
Странности в bash
Хардуерни и софтуерни проблеми
qwert 3 8321 Последна публикация Jun 22, 2007, 10:39
от qwert
Bash скрипт
Настройка на програми
empty 39 18026 Последна публикация Aug 25, 2007, 00:31
от VladSun
Bash
Настройка на програми
tony1975 9 3296 Последна публикация Sep 03, 2007, 15:38
от VladSun