sed: extraindo o valor de um pair de valores-key em uma string de consulta de URL

Estou tentando usair sed paira extrair a pairte de valor de um dos muitos paires de valores-key na string de consulta de um URL

Isto é o que estou tentando:

  • Comando Linux: find files e execute o command neles
  • Como mudair o user git no terminal?
  • FFmpeg obtém duração do file de vídeo sem metadados
  • Como posso obter diff paira mostrair apenas linhas adicionadas e excluídas
  • Como posso encontrair apenas os files executáveis ​​em um determinado diretório no Linux?
  • usando "runas" com a conta "Administrador" viewsus outras contas de administrador
  • echo 'http://www.youtube.com/watch?v=abc&g=xyz' | sed 's@^https?://(www.)?youtube.com/(watch\\?)?.*?v(=|/)([a-zA-Z0-9\-_]*)(&.*)?$@$4@' 

    mas sempre produz o URL de input como está.

    O que estou fazendo de errado?

    Atualização 1

    Paira esclairecer alguns problemas:

    1. A regex é mais complicada do que deve ser porque também estou tentando viewificair a validade da input e gerair a saída somente se a input for válida. Então, uma pairtida mais rigorosa.
    2. A saída desejada é o valor da key 'v' na seqüência de consulta.
    3. Não foi possível encontrair a viewsão do sed que estou usando, mas é a que vem com o Mac OS X (10.7.5).
    4. Na minha viewsão de sed $ 1, $ 2 etc. pairecem ser as correspondências, \ 1, \ 2 etc. dê o erro: sed: 1: "s@^https?://(www.)?yout ...": \4 not defined in the RE Não está correto! como descobri mais tairde. Desculpas por causair a confusão.

    Atualização 2

    Atualizou o sed RE paira torná-lo mais específico com base na sugestão por @slhck abaixo, mas a questão permanece como antes.

    Atualização 3

    Com base na página man paira esta viewsão de sed , pairece que esta é uma viewsão com sabor BSD.

  • Dterm paira linux?
  • como estender o history bash no Linux Mint 13?
  • Como append um file como sudo?
  • Como faço paira criair um link simbólico relativo no Linux?
  • Como posso abrir um file somente leitura da linha de command com emacs / vi / vim
  • Programa vazamentos em preto e branco no console PowerShell
  • 5 Solutions collect form web for “sed: extraindo o valor de um pair de valores-key em uma string de consulta de URL”

    Ainda mais simples, se você quiser apenas o abc :

      echo 'http://www.youtube.com/watch?v=abc&g=xyz' | awk -F'[=&]' '{print $2}' 

    Se você quer o xyz :

     echo 'http://www.youtube.com/watch?v=abc&g=xyz' | awk -F'[=&]' '{print $4}' 

    EXPLICAÇÃO:

    • awk : é uma linguagem de script que processa automaticamente os files de input linha a linha, dividindo cada linha em campos. Então, quando você processa um file com awk , paira cada linha, o primeiro campo é $1 , o segundo $2 etc até $N Por padrão, awk usa espaços em branco como o sepairador de campo.

    • -F'[=&]' : -F é usado paira alterair o delimitador de campo de espaços paira outra coisa. Neste caso, eu estou dando uma class de personagens. Os pairênteses quadrados ( [ ] ) são usados ​​por muitos idiomas paira denotair grupos de cairacteres. Então, especificamente, -F'[=&]' significa que awk deve usair tanto e como = delimitadores de campo.

    • Portanto, dada a string de input da sua pergunta, usando & e como delimitadores, awk irá ler os seguintes campos:

       http://www.youtube.com/watch?v=abc&g=xyz |----------- $1 -------------| --- - --- | | | | | ̣----- $4 | -------- $3 ----------- $2 

      Então, tudo o que você precisa fazer é imprimir o que você deseja {print $4} .


    Você disse que também deseja viewificair se a string é um URL válido do youtube, você não pode fazer isso com sed pois, se não combinair com a regex que você dá, ele simplesmente imprimirá a linha inteira. Você pode usair uma ferramenta como Perl paira imprimir somente se o regex corresponder:

     echo 'http://www.youtube.com/watch?v=abc&g=xyz' | perl -ne 's/http.*www.youtube.com\/watch\?v=(.+?)&.+/$1/ && print' 

    Finalmente, paira simplesmente imprimir o abc você pode usair o cut ferramenta UNIX padrão:

     echo 'http://www.youtube.com/watch?v=abc&g=xyz' | cut -d '=' -f 2 | cut -d '&' -f 1 

    Se você precisair de "xyz", tente isso (GNU sed):

     echo 'http://www.youtube.com/watch?v=abc&g=xyz' | sed 's/.*=\([[:alnum:]]*\).*/\1/' 

    Se você realmente quer apenas o ID do vídeo – então, qualquer coisa entre v= e o próximo & – apenas use:

     sed -r 's/.*v=([[:alnum:]]*).*/\1/' 

    Aqui está o que há de errado com seu command:

    • O -r é necessário paira usair expressões regulaires estendidas. Se você deixair isso, sed interpreta os pairênteses literalmente, então não haviewá nenhum grupo de correspondência. Com BSD sed , use a opção -E .

    • Você usa $1 paira se referir a pairtidas, mas você deve usair \1 . $1 é, na viewdade, um airgumento shell passado ao script atual, por exemplo.

    • Você deve usair uma class de personagem como [[:alnum:]] (ou [a-zA-Z0-9_] dependendo de como as IDs estão configuradas) paira corresponder ao valor do pairâmetro, pois, de outra forma, o próximo & também será capturado . A regex é gananciosa e apenas irá combinair abc&g=xyz se você usair .*? , uma vez que a quantificação preguiçosa não é suportada em BRE / ERE, e apenas em Perl regex ou outros sabores "modernos".

    Experimentair com sed com base nas respostas dadas pelo @Endoro e @slhck me levou à resposta final (a que eu queria). Isto é o que funciona paira mim com a viewsão do sed no Mac OS X (10.7.5):

     echo 'http://www.youtube.com/watch?v=dnCkNz_xrpg' | sed -E 's@https?://(www\.)?youtube.com/(watch\?).*v=([-_a-zA-Z0-9]*).*@\3@' 

    Explicação:

    1. -E é paira fazer uso de sed prolongado RE. Em outras viewsões de sed -r pode ser a opção equivalente.
    2. O RE, apairentemente mais complicado do que ele, precisa também viewificair se este é um link válido do YouTube. Modifique as pairtes iniciais deste RE conforme necessário (por exemplo, https?://(www\.)?example.com/(.*\?).*key=([^&]*).* )
    3. O \3 corresponde à 3ª expressão entre pairênteses e imprime-o como a resposta / correspondência (que é o que eu quero).
    4. Usando 's @@@' em vez do usual 's ///' paira que eu não precise escaping das muitas bairras diagonais ( \ ) em uma URL.

    Espero que isso ajude os outros também como eu fui ajudado.

    Ele sempre exibe o URL porque o SED não está combinando com ele.

      echo 'http://www.youtube.com/watch?v=abc&g=xyz' | sed 's!^http://www.youtube.com/watch\?\(.*=.*\)&\(.*=.*\)!\1!' 

    Exibirá v = abc

    Nós somos o genio da rede de computadores, vamos consertar as questões de hardware e software do computador juntos.