Автор Тема: [BASH] While яде първия знак, на вас случвало ли се е?  (Прочетена 16938 пъти)

go_fire

  • Global Moderator
  • Напреднали
  • *****
  • Публикации: 8780
  • Distribution: Дебиан Сид
  • Window Manager: ROX-Desktop / е17
  • кашик с гранатомет в танково поделение
    • Профил
    • WWW
Значи говорим за стандартната (крадена от Интернет) конструкция на Докато:

Код
GeSHi (Bash):
  1. while read -r line; do command "$line"; done <file

Досега успешно съм я ползвал на други места. Единствената разлика е, че преди въпросното file всъщност е било $1, а сега името е твърдо установено.

Обаче след първата врътка, всяка следваща променлива $line започва да ѝ липсва първия знак от реда. Така реално си зациклям на втора врътка с грешка и не мога да продължа.

Някой има ли идея, защо се случва?

А, ако няма, ще съм благодарен и на идея, с какво да сменя Докато. Лесно е да се каже За, но не се сещам как да го накарам да работи за всеки ред от текстов документ.

Благодаря на отзовалите се, както и на тези, които просто са наминали!
Активен

В $por4e2 e истината  ;)

***

Aко даваха стипендия за най-глупави, щях да съм човека с най-много Mини Kупъри

***

Reborn since 1998 || 15.09.2007 totally М$ free && conscience clear

makeme

  • Напреднали
  • *****
  • Публикации: 895
  • Distribution: Many
  • Window Manager: KDE
    • Профил
Значи говорим за стандартната (крадена от Интернет) конструкция на Докато:

Код
GeSHi (Bash):
  1. while read -r line; do command "$line"; done <file

Досега успешно съм я ползвал на други места. Единствената разлика е, че преди въпросното file всъщност е било $1, а сега името е твърдо установено.

Обаче след първата врътка, всяка следваща променлива $line започва да ѝ липсва първия знак от реда. Така реално си зациклям на втора врътка с грешка и не мога да продължа.

Някой има ли идея, защо се случва?

А, ако няма, ще съм благодарен и на идея, с какво да сменя Докато. Лесно е да се каже За, но не се сещам как да го накарам да работи за всеки ред от текстов документ.

Благодаря на отзовалите се, както и на тези, които просто са наминали!
При мен работи. command=echo Та да не би да е от командата? Смисъл - ако е echo пак ли ги реже?
Активен

Distributions:  UbuntuMate; Kubuntu; CentOS; Kali; Raspberry Pi OS ...

go_fire

  • Global Moderator
  • Напреднали
  • *****
  • Публикации: 8780
  • Distribution: Дебиан Сид
  • Window Manager: ROX-Desktop / е17
  • кашик с гранатомет в танково поделение
    • Профил
    • WWW
Е не, командата хич не е една, бая команди работят върху $line. Все пак си говорим за над сто реда, сложно, следователно чупливо нещо, което нявга беше възможно само с няколко буквички и цифрички. Но, че цикъла Докато го яде, съм сигурен, защото наслагах проверки навсякъде. И като най-после сложих следващия ред след Докато да е echo $var, истината цъфна.
Активен

В $por4e2 e истината  ;)

***

Aко даваха стипендия за най-глупави, щях да съм човека с най-много Mини Kупъри

***

Reborn since 1998 || 15.09.2007 totally М$ free && conscience clear

jet

  • Напреднали
  • *****
  • Публикации: 3472
  • Distribution: debian
  • Window Manager: kde
    • Профил
абе и при мен си работи без да реже (c echo)
Пробвай да смениш шибанга
#!/bin/bash
с
#!/bin/sh
Активен

..⢀⣴⠾⠻⢶⣦⠀
  ⣾⠁⢠⠒⠀⣿⡁
  ⢿⡄⠘⠷⠚⠋
  ⠈⠳⣄⠀⠀⠀⠀  Debian, the universal operating system.

remotexx

  • Напреднали
  • *****
  • Публикации: 3210
    • Профил
...можеш ли да качиш примерен зип файл некаде че да тестваме - само с 2-3 реда - може да смениш/скриеш текста само не барай делимитерите и новите редове

неколко идеи
- що не пробваш с -u filename опцията, да не конзолата/шела да прекодира некой символи при пренасочването
- първия символ дето го яде да не енякой специален или е случайна буква
- тук пише: Only the characters found in $IFS are recognized as word delimiters.
http://linuxcommand.org/lc3_man_pages/readh.html

за проба с файлов дескриптор - долното дали ще работи правилно
Код
GeSHi (Bash):
  1. #!/bin/bash
  2. FILE=$1
  3. # read $FILE using the file descriptors
  4. exec 3<&0
  5. exec 0<$FILE
  6. while read line
  7. do
  8. # use $line variable to process line
  9. echo $line
  10. done
  11. exec 0<&3
Активен

go_fire

  • Global Moderator
  • Напреднали
  • *****
  • Публикации: 8780
  • Distribution: Дебиан Сид
  • Window Manager: ROX-Desktop / е17
  • кашик с гранатомет в танково поделение
    • Профил
    • WWW
Джет, #! ми е важен да е bash, защото ползвам възможности специфични за басх, които ги няма в sh. Ремо, аз никога не съм си крил кода. Ще го дам целия. В този си вид той работи само за един ред, което прави повечето код излишен. Под него ще дам кратки обяснения за бързо влизане в ситуацията.

Код
GeSHi (Bash):
  1. #!/bin/bash
  2.  
  3. unset y f l d ft
  4. declare -a yar
  5. declare -a far
  6.  
  7.  
  8. echo "Loading..."
  9.  
  10.  
  11. if [ oti -nt oti2 ]; then
  12.  
  13.    y=$(youtube-dl --get-id -a oti)
  14.    echo "$y" > "oti2"
  15.  
  16.  
  17.  
  18.    #https://askubuntu.com/questions/62492/how-can-i-change-the-date-modified-created-of-a-file
  19.    touch -d "$(date -R -r oti)" oti2
  20.  
  21.  
  22. fi
  23.  
  24. echo "Check..."
  25.  
  26. while read -r l;
  27. do
  28.    echo "$l e super";
  29.  
  30.    if [ -f *"$l.mkv" ]; then
  31.  
  32. echo "Matroska: OK"
  33.  
  34.    else
  35.  
  36. if [ -f *"$l.mp4" ]; then
  37.  
  38.    far[0]="*$l.mp4"
  39.  
  40.    if [ -f *"$l.m4a" ]; then
  41. far[5]="m4a"
  42.    else      
  43. far[5]="webm"
  44.  
  45.    fi
  46.  
  47.    echo "Convert..."
  48.  
  49.  
  50.    far[1]=$(echo ${far[0]})
  51.    far[4]=${far[1]:0:-3}
  52.  
  53.    far[2]=${far[4]}${far[5]}
  54.  
  55.    far[6]="mkv"
  56.    far[3]=${far[4]}${far[6]}
  57.  
  58.    ffmpeg -i "${far[1]}" -i "${far[2]}" -c:v copy -c:a copy -strict experimental "${far[3]}"
  59.    d=$(date -R -r "${far[1]}")
  60.    touch -d "$d" "${far[3]}"
  61.    rm "${far[1]}" "${far[2]}"
  62.  
  63. else
  64.  
  65.    ft="597/160/133"
  66.    if [ -f *"$l.m4a" ]; then
  67.  
  68. yar[1]="youtube-dl --download-archive ito -f "$ft" $l &"
  69.  
  70.    elif [ -f *"$l.webm" ]; then
  71.  
  72. yar[1]="youtube-dl --download-archive ito -f "$ft" $l &"
  73.  
  74. if [ -f *"$l.m4a."* ]; then
  75.    rm  *"$l.m4a."*
  76. fi
  77.  
  78.    else
  79.  
  80. ft="599/600/249/250/139/251/140"
  81.  
  82. yar[1]="youtube-dl -f "$ft" $l &"
  83.  
  84.  
  85. echo "tralala 3 $l"
  86.  
  87.    fi
  88.  
  89.    if [ -f "$l" ]; then
  90.  
  91. f=$(cat $l)
  92.  
  93.    else
  94.  
  95. f=$(youtube-dl --get-filename -f $ft $l)
  96.  
  97. echo "$f" > $l
  98. touch "$f.part"
  99.  
  100.    fi
  101.  
  102.  
  103.    yar[0]='for i in `seq 1 20`;do if [ -f "'$f'.part" ]; then '
  104.    yar[2]=' sleep 200 && pkill -9 youtube-dl; else rm $0 "'$l'" && ./for & exit ;fi ;done'
  105.  
  106.    echo ${yar[0]}${yar[1]}${yar[2]} > for2
  107.  
  108.    echo "Download..."
  109.  
  110.    sh for2 &
  111.    echo "bibi  $l"
  112.    exit
  113.  
  114. fi
  115.  
  116.    fi
  117.  
  118.  
  119. done < oti2
  120.  
  121. rm  oti2
  122.  
  123. echo "Done!"
  124.  
  125.  
  126. exit
  127.  

Както казах, това би било полезно единствено на някой, който иска да гледа клипчета с включено видео от тубата, но не разполага с кабелна връзка. Целта е да се случи същото, каквото правеше youtube-dl -f 17/36 почти толкова добре. Понеже реално 3gp не съществува вече в тубата, то няма как да се докара точно същото.

Понеже става въпрос за много бавни операции, то съм направил малко хакове. Информацията, която ми доставя youtube-dl я записвам във временни файлове. Това се случва на три места.

Първото. На тринадесети ред се подава списъка за теглене (реда y=$(youtube-dl --get-id -a oti)), който се записва във временен документ наречен oti2. Точно върху него правя упражнението while read. Защо така? Ами защото стандартен списък може да съдържа коментари, освен това може да се промени докато се чака изпълнение. Напомням, че си говорим за упражнение, което грубо трае до към тройно време на дължината на клиповете. Така, ако тегля клип от половин час, той ще е при мен грубо след малко под два часа. Ако правех същото на разделителна способност от 640x360 да речем, то той би бил при мен след 2 до 3 дни. Определено в това време могат да се сменят доста неща.

Второто обръщение към y-dl e на ред 95 (f=$(youtube-dl --get-filename -f $ft $l)). Него го правя, за да науча името на бъдещия клип, което записвам във временен  документ именуван с индификатора на клипа. Точно това е и съдържанието на oti2. Понеже заявка за името е отново много бавна операция, се старая да я извиквам възможно най-рядко. Понеже тегля два формата (по един за видео и аудио), то имам две такива обръщения. Можеше да е едно (и да правя подниз на низ, substring), но понеже аудиото може да е във формат webm или m4a (webm не винаги е наличен), то би станало още по-трошливо от сега.

Третата заявка към y-dl се сглобява и налива във временен документ наречен for2.

ВАЖНО! Ако ще пробвате нещото, сменете стойността 200 от ред 104 на примерно 5.

На добра връзка едно клипче от пет минути се тегли за около пет секунди.

При мен е сложено двеста, защото опитно съм установил, че y-dl умира на всеки две-три минути, но се случва и на повече. Затова съм му дал време за мислене малко над три минути. Това е нещо, което се случва само на бавни скорости. На бързи, y-dl не умира, но мен ме интересуват бавните.

Този for2 е фактически нещото, което се изпълнява в подобвивка (subshell). Причината за това е, защото bash няма goto. Втората причина е, че bash не е език за програмиране, а команден набор и няма вложени цикли. Ако нещо влезе в подобвивка на подобвивка, то просто бива убито. Всичко трябва да е на най-много две плоскости.

=*=

Начина да се опита работата на горния код е следния:

1. Намирате си три произволни клипчета от тубата. Няма нужда от повече, още второто няма да бъде изтеглено.

2. Правите си временен каталог. Това е за сигурност. Само луд би вярвал в способностите ми.

3. Правите вътре документ наречен oti (може и друго, но трябва да промените кода). Слагате адресите на трите клипчета като отделни редове. Y-dl не се интересува от празни редове и коментари в няколко варианта, включително безценните за мен # и ;.

4. Изпълнявате кода като му подавате въпросния oti.

5. Ако сте на бърза връзка, в никакъв случай не забравяте да промените онова 200 на например 5.
Активен

В $por4e2 e истината  ;)

***

Aко даваха стипендия за най-глупави, щях да съм човека с най-много Mини Kупъри

***

Reborn since 1998 || 15.09.2007 totally М$ free && conscience clear

jet

  • Напреднали
  • *****
  • Публикации: 3472
  • Distribution: debian
  • Window Manager: kde
    • Профил
Ремо не го разбра - той искаше файла с данните.
Активен

..⢀⣴⠾⠻⢶⣦⠀
  ⣾⠁⢠⠒⠀⣿⡁
  ⢿⡄⠘⠷⠚⠋
  ⠈⠳⣄⠀⠀⠀⠀  Debian, the universal operating system.

go_fire

  • Global Moderator
  • Напреднали
  • *****
  • Публикации: 8780
  • Distribution: Дебиан Сид
  • Window Manager: ROX-Desktop / е17
  • кашик с гранатомет в танково поделение
    • Профил
    • WWW
Ами ето един:

Цитат
https://www.youtube.com/watch?v=udGtY2bmTxs
https://www.youtube.com/watch?v=tq8iJgRImH8
https://www.youtube.com/watch?v=tjUBP9m3M5E

Това са първите три в:

https://www.youtube.com/feed/trending?disable_polymer=1

Съответно oti2 (върху който се цикли), би съдържал:

Цитат
udGtY2bmTxs
tq8iJgRImH8
tjUBP9m3M5E

Единственото друго вътре би било край на ред (проверено).

Всички индефикатори на тубата се състоят от единадесет на брой латински букви, цифри и тире. Никакви други знаци не съм виждал. Пробвах с множество примери, винаги първата се реже. И дори не е била тире. При последните няколко бяха „j“ „U“ и „8“.
Активен

В $por4e2 e истината  ;)

***

Aко даваха стипендия за най-глупави, щях да съм човека с най-много Mини Kупъри

***

Reborn since 1998 || 15.09.2007 totally М$ free && conscience clear

laskov

  • Напреднали
  • *****
  • Публикации: 3166
    • Профил
Сложи по един фиктивен знак като първи. Може да е интервал, а може и едно голямо L в моя чест :)
Активен

Не си мислете, че понеже Вие мислите правилно, всички мислят като Вас! Затова, когато има избори, идете и гласувайте, за да не сте изненадани после от резултата, и за да не твърди всяка партия, че тя е спечелила, а Б.Б. (С.С., ...) е загубил, а трети да управлява.  Наздраве!  [_]3

4096bits

  • Напреднали
  • *****
  • Публикации: 6152
    • Профил
Защо не извлечеш IDтата директно от адресите в списъка, а правиш запитване към youtube?
Активен

As they say in Mexico, "Dasvidaniya!" Down there, that's two vidaniyas.

go_fire

  • Global Moderator
  • Напреднали
  • *****
  • Публикации: 8780
  • Distribution: Дебиан Сид
  • Window Manager: ROX-Desktop / е17
  • кашик с гранатомет в танково поделение
    • Профил
    • WWW
Защо не извлечеш IDтата директно от адресите в списъка, а правиш запитване към youtube?

Защото списъка може да (и почти винаги) съдържа празни редове и коментари. За да свърша същото на bash, трябваше да имам поне още двадесет реда логика. А логиката на bash е много трошлвива.
Активен

В $por4e2 e истината  ;)

***

Aко даваха стипендия за най-глупави, щях да съм човека с най-много Mини Kупъри

***

Reborn since 1998 || 15.09.2007 totally М$ free && conscience clear

4096bits

  • Напреднали
  • *****
  • Публикации: 6152
    • Профил
Какво искаш да направиш стъпка по стъпка?
Може да пробвам да сглобя нещо на Питоня
Активен

As they say in Mexico, "Dasvidaniya!" Down there, that's two vidaniyas.

makeme

  • Напреднали
  • *****
  • Публикации: 895
  • Distribution: Many
  • Window Manager: KDE
    • Профил
При мен скрипта не върви, ма може да е от 100 неща. Ако имам време ще го погледна, но ако идеята ти е да сваляш най-кофти формата , има по лесни варианти :)

Цитат
       You  can  also  use  a  file  extension (currently 3gp, aac, flv, m4a, mp3, mp4, ogg, wav, webm are supported) to download the best quality format of a particular file extension
       served as a single file, e.g.  -f webm will download the best quality format with the webm extension served as a single file.

       You can also use special names to select particular edge case formats:

       · best: Select the best quality format represented by a single file with video and audio.

       · worst: Select the worst quality format represented by a single file with video and audio.

       · bestvideo: Select the best quality video-only format (e.g.  DASH video).  May not be available.

       · worstvideo: Select the worst quality video-only format.  May not be available.

       · bestaudio: Select the best quality audio only-format.  May not be available.

       · worstaudio: Select the worst quality audio only-format.  May not be available.


При мен е обратното разбира се. Аз търся най-хубавия:
Код
GeSHi (Bash):
  1. alias youtube-dl='youtube-dl -f '\''bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best'\'''

Ако не ти е това идеята, моля обясни каква е :)
Активен

Distributions:  UbuntuMate; Kubuntu; CentOS; Kali; Raspberry Pi OS ...

4096bits

  • Напреднали
  • *****
  • Публикации: 6152
    • Профил
Ами аз се опитах да си го преведа, обаче синтаксиса на bash ми мътна работа все още. Така и не го научих.
Активен

As they say in Mexico, "Dasvidaniya!" Down there, that's two vidaniyas.

makeme

  • Напреднали
  • *****
  • Публикации: 895
  • Distribution: Many
  • Window Manager: KDE
    • Профил
Ами аз се опитах да си го преведа, обаче синтаксиса на bash ми мътна работа все още. Така и не го научих.
Аз що годе го чаткам, ма Гого е сътворил някаква странна манджа :)
Не мога да схвана изобщо логиката. Например това:

Код:
f=$(youtube-dl --get-filename -f $ft $l)
 
echo "$f" > $l
touch "$f.part"

казва дай ми Името на клипа от това ИД и после замени ИДто с името.. :) Дори не знам дали ще може да го направи баш.
ПП: Схванах го. Прави си фаелче с името на ИДто :)
« Последна редакция: Mar 28, 2020, 07:35 от makeme »
Активен

Distributions:  UbuntuMate; Kubuntu; CentOS; Kali; Raspberry Pi OS ...

Подобни теми
Заглавие Започната от Отговора Прегледи Последна публикация
bash срипт за местене на файлове
Общ форум
nov_chovek 3 2090 Последна публикация Oct 27, 2009, 16:17
от radoulov
Bash - взимане на няколко реда от средата на текст файл
Общ форум
PhrozenCrew 7 2128 Последна публикация Dec 04, 2009, 15:35
от radoulov
bash проблемче
Общ форум
asp 3 2112 Последна публикация Jun 21, 2010, 19:13
от asp
Питанка за bash скрипт
Общ форум
p1k0 9 2707 Последна публикация Sep 05, 2010, 02:47
от neter
bash + php
Общ форум
mrowcp 5 2153 Последна публикация Sep 06, 2010, 17:23
от neter