AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / computer / Perguntas / 1660844
Accepted
Hashim Aziz
Hashim Aziz
Asked: 2021-07-06 09:23:06 +0800 CST2021-07-06 09:23:06 +0800 CST 2021-07-06 09:23:06 +0800 CST

Usando read para capturar várias variáveis ​​da saída de um comando

  • 772

Eu tenho um youtube-dlcomando que, quando executado, gera duas novas linhas e estou tentando capturar cada uma delas para variáveis.

Aqui está o que tenho até agora, mas por algum motivo não consigo entender, ele apenas captura a primeira linha de saída enquanto descarta a segunda ( $audioestá vazia).

read -r video audio <<< "$(youtube-dl -g --youtube-skip-dash-manifest https://www.youtube.com/watch?v=-gcvAxJJiGo)"

Como posso corrigi-lo para capturar as duas entradas ou, alternativamente, existe uma maneira mais confiável de fazer isso?

bash command-line
  • 2 2 respostas
  • 866 Views

2 respostas

  • Voted
  1. Kamil Maciorowski
    2021-07-06T10:02:06+08:002021-07-06T10:02:06+08:00

    readlê uma linha por design . A maneira mais simples de ler duas linhas é usar readduas vezes.

    exec 3< <(youtube-dl -g --youtube-skip-dash-manifest 'https://www.youtube.com/watch?v=-gcvAxJJiGo')
    IFS= read -r -u3 video
    IFS= read -r -u3 audio
    exec 3>&-
    

    read -unão é portátil, nem é<(…) . Eles funcionam no Bash e sua pergunta é marcada como bash , então eles devem funcionar para você.

    Observe que coloquei entre aspas simples a string que contém ?caso você tenha um diretório https:/www.youtube.com/e um arquivo correspondente nele. É apenas remotamente possível, ainda citar caracteres curinga que não devem ser tratados como curingas é uma boa prática em qualquer shell. Compare o que acontece em Zsh .

    Vazio IFS é a coisa certa em geral , quando você quer ler uma linha.

    Esta outra resposta não usa exece é boa. É minha preferência pessoal configurar a entrada visualmente antes das ferramentas que a usarão (compare esta resposta ). Infelizmente <(…) { …; }não funciona. Com execeu consigo.

    Ou posso fazer isso canalizando youtube-dlpara o resto do script.

    youtube-dl -g --youtube-skip-dash-manifest 'https://www.youtube.com/watch?v=-gcvAxJJiGo' \
    | {
    IFS= read -r video
    IFS= read -r audio
    }
    

    Normalmente, o Bash executa o { … }fragmento em um subshell, portanto, as variáveis ​​não sobreviverão após o }. shopt -s lastpipepode alterar isso (se o controle de trabalho não estiver ativo). Sem lastpipe(o que não é portátil) toda a abordagem é portátil, mas você precisa executar tudo que usa as variáveis ​​dentro do { }bloco porque você não sabe se é um subshell ou não (POSIX permite os dois comportamentos). Observe que o stdin dentro do bloco vem de youtube-dl; se alguma coisa dentro do bloco precisar usar o stdin de todo o script, talvez você precise usar execde qualquer maneira para fazer malabarismos com os descritores.

    Outra abordagem portátil é assim:

    input="$(youtube-dl -g --youtube-skip-dash-manifest 'https://www.youtube.com/watch?v=-gcvAxJJiGo')"
    video="$(printf '%s\n' "$input" | head -n 1)"
    audio="$(printf '%s\n' "$input" | head -n 2 | tail -n 1)"
    

    Em vez de heade tailvocê pode usar sedou awkpara isolar a linha certa.

    Observe que esta solução não usa arquivos read. Se você precisa de recursos read, então este não é o caminho. Parece que você não precisa dos recursos readneste caso específico.

    Mesmo que youtube-dlfosse muito rápido, eu não aconselharia video="$(youtube-dl … | head -n 1)"mais audio="$(youtube-dl … | …)". Se videoe audiovêm do mesmo input, da mesma invocação de youtube-dl, então eles são tão coerentes quanto a ferramenta permite. Caso contrário, podem ser incoerentes. Francamente, não sei quão incoerentes podem ser (se alguma vez); mas eu sei que em geral é melhor consultar uma vez (por exemplo date +%H:+%M, deve sempre ser coerente; date +%H; date +%Mvai surpreendê-lo se você executá-lo pouco antes de uma hora).

    • 3
  2. Best Answer
    glenn jackman
    2021-07-06T10:20:26+08:002021-07-06T10:20:26+08:00

    read -r video audioirá capturar a primeira palavra ($IFS separada) em "vídeo" e o resto da linha em "áudio"

    Outra maneira de capturar 2 linhas é com agrupamento de comandos e uma substituição de processo:

    {
      read -r video
      read -r audio
    } < <(
      youtube-dl -g --youtube-skip-dash-manifest "$url"
    )
    

    O espaço entre < <(é importante: a <(process substitution)age como um arquivo, então você está usando <para redirecionar a entrada de um arquivo.


    Acabou de me ocorrer: outra maneira de ler as linhas de saída é o mapfilecomando:

    mapfile -t lines < <(youtube-dl ...)
    declare -p lines  # just to inspect the array contents
    
    video=${lines[0]}
    audio=${lines[1]}
    
    • 3

relate perguntas

  • Existe um equivalente a cd - para cp ou mv?

  • Qual seria o equivalente em lote do argumento "pass" do Python?

  • Não é possível ativar o Microsoft Print to PDF depois de desativado

  • Notificar-enviar notificações aparecendo na janela

  • como abrir um arquivo de escritório do WSL

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Como posso reduzir o consumo do processo `vmmem`?

    • 11 respostas
  • Marko Smith

    Baixar vídeo do Microsoft Stream

    • 4 respostas
  • Marko Smith

    O Google Chrome DevTools falhou ao analisar o SourceMap: chrome-extension

    • 6 respostas
  • Marko Smith

    O visualizador de fotos do Windows não pode ser executado porque não há memória suficiente?

    • 5 respostas
  • Marko Smith

    Como faço para ativar o WindowsXP agora que o suporte acabou?

    • 6 respostas
  • Marko Smith

    Área de trabalho remota congelando intermitentemente

    • 7 respostas
  • Marko Smith

    O que significa ter uma máscara de sub-rede /32?

    • 6 respostas
  • Marko Smith

    Ponteiro do mouse movendo-se nas teclas de seta pressionadas no Windows?

    • 1 respostas
  • Marko Smith

    O VirtualBox falha ao iniciar com VERR_NEM_VM_CREATE_FAILED

    • 8 respostas
  • Marko Smith

    Os aplicativos não aparecem nas configurações de privacidade da câmera e do microfone no MacBook

    • 5 respostas
  • Martin Hope
    Saaru Lindestøkke Por que os arquivos tar.xz são 15x menores ao usar a biblioteca tar do Python em comparação com o tar do macOS? 2021-03-14 09:37:48 +0800 CST
  • Martin Hope
    CiaranWelsh Como posso reduzir o consumo do processo `vmmem`? 2020-06-10 02:06:58 +0800 CST
  • Martin Hope
    Jim Pesquisa do Windows 10 não está carregando, mostrando janela em branco 2020-02-06 03:28:26 +0800 CST
  • Martin Hope
    v15 Por que uma conexão de Internet gigabit/s via cabo (coaxial) não oferece velocidades simétricas como fibra? 2020-01-25 08:53:31 +0800 CST
  • Martin Hope
    andre_ss6 Área de trabalho remota congelando intermitentemente 2019-09-11 12:56:40 +0800 CST
  • Martin Hope
    Riley Carney Por que colocar um ponto após o URL remove as informações de login? 2019-08-06 10:59:24 +0800 CST
  • Martin Hope
    zdimension Ponteiro do mouse movendo-se nas teclas de seta pressionadas no Windows? 2019-08-04 06:39:57 +0800 CST
  • Martin Hope
    jonsca Todos os meus complementos do Firefox foram desativados repentinamente, como posso reativá-los? 2019-05-04 17:58:52 +0800 CST
  • Martin Hope
    MCK É possível criar um código QR usando texto? 2019-04-02 06:32:14 +0800 CST
  • Martin Hope
    SoniEx2 Altere o nome da ramificação padrão do git init 2019-04-01 06:16:56 +0800 CST

Hot tag

windows-10 linux windows microsoft-excel networking ubuntu worksheet-function bash command-line hard-drive

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve