Come posso codificare e decodificare stringhe con codifica percentuale sulla riga di comando?


31

Come posso codificare e decodificare stringhe con codifica percentuale (codifica URL) sulla riga di comando?

Sto cercando una soluzione che può fare questo:

$ percent-encode "ændrük"
%C3%A6ndr%C3%BCk
$ percent-decode "%C3%A6ndr%C3%BCk"
ændrük

Vuoi incorporare anche codifiche diverse? %E6ndr%FCknon sembra (standard) UTF8 per me. O è solo un esempio?
organizzare il

@arrange Grazie per averlo colto. Apparentemente ho scelto la mela cattiva tra i risultati di ricerca per i convertitori online.
ændrük,

Risposte:


35

Questi comandi fanno quello che vuoi:

python -c "import urllib, sys; print urllib.quote(sys.argv[1])" æ
python -c "import urllib, sys; print urllib.unquote(sys.argv[1])" %C3%A6

Se si desidera codificare gli spazi come +, sostituirli urllib.quotecon urllib.quote_plus.

Immagino che vorrai aliasli ;-)


1
Cos'è quel personaggio alla fine della prima riga? Modifica: rispondendo a me stesso - capito, è solo una stringa UTF8 da codificare con un singolo carattere per esempio scopo :-)
TMG

1
che ne dici di python3?
Ricardo E

@RicardoE controlla questa risposta .
Pablo A

27

conchiglia

Prova la seguente riga di comando:

$ echo "%C3%A6ndr%C3%BCk" | sed 's@+@ @g;s@%@\\x@g' | xargs -0 printf "%b"
ændrük

È possibile definirlo come alias e aggiungerlo ai file rc della shell :

$ alias urldecode='sed "s@+@ @g;s@%@\\\\x@g" | xargs -0 printf "%b"'

Quindi ogni volta che ne hai bisogno, vai semplicemente con:

$ echo "http%3A%2F%2Fwww" | urldecode
http://www

bash

Durante lo scripting, è possibile utilizzare la sintassi seguente:

input="http%3A%2F%2Fwww"
decoded=$(printf '%b' "${input//%/\\x}")

Tuttavia la sintassi precedente non gestirà +correttamente i plus ( ), quindi è necessario sostituirli con spazi tramite sed.

È inoltre possibile utilizzare le seguenti funzioni urlencode()e urldecode()funzioni:

urlencode() {
    # urlencode <string>
    local length="${#1}"
    for (( i = 0; i < length; i++ )); do
        local c="${1:i:1}"
        case $c in
            [a-zA-Z0-9.~_-]) printf "$c" ;;
            *) printf '%%%02X' "'$c"
        esac
    done
}

urldecode() {
    # urldecode <string>

    local url_encoded="${1//+/ }"
    printf '%b' "${url_encoded//%/\\x}"
}

Nota che il tuo urldecode () presume che i dati non contengano barre rovesciate.


bash + xxd

Funzione Bash con xxdstrumento:

urlencode() {
  local length="${#1}"
  for (( i = 0; i < length; i++ )); do
    local c="${1:i:1}"
    case $c in
      [a-zA-Z0-9.~_-]) printf "$c" ;;
    *) printf "$c" | xxd -p -c1 | while read x;do printf "%%%s" "$x";done
  esac
done
}

Si trova nel file gist di cdown , anche su StackOverflow .


Pitone

Prova a definire i seguenti alias:

alias urldecode='python -c "import sys, urllib as ul; print ul.unquote_plus(sys.argv[1])"'
alias urlencode='python -c "import sys, urllib as ul; print ul.quote_plus(sys.argv[1])"'

Uso:

$ urlencode "ændrük"
C%26ndrC%3Ck
$ urldecode "%C3%A6ndr%C3%BCk"
ændrük

Fonte: ruslanspivak


PHP

Utilizzando PHP puoi provare il seguente comando:

$ echo oil+and+gas | php -r 'echo urldecode(fgets(STDIN));' // Or: php://stdin
oil and gas

o semplicemente:

php -r 'echo urldecode("oil+and+gas");'

Utilizzare -Rper input su più righe.


Perl

In Perl puoi usare URI::Escape.

decoded_url=$(perl -MURI::Escape -e 'print uri_unescape($ARGV[0])' "$encoded_url")

O per elaborare un file:

perl -i -MURI::Escape -e 'print uri_unescape($ARGV[0])' file

sed

L'utilizzo sedpuò essere ottenuto mediante:

cat file | sed -e's/%\([0-9A-F][0-9A-F]\)/\\\\\x\1/g' | xargs echo -e

awk

Prova una soluzione anon :

awk -niord '{printf RT?$0chr("0x"substr(RT,2)):$0}' RS=%..

Vedere: Utilizzo di awk printf per codificare il testo .


decodifica dei nomi dei file

Se è necessario rimuovere la codifica URL dai nomi dei file, utilizzare lo deurlnamestrumento da renameutils(ad es deurlname *.*.).

Guarda anche:


Relazionato:


La versione bash + xxd non funziona con stringhe che contengono un %, forse potresti sostituirlo printf "$c"con printf "%c" "$c"? Un altro problema è che alcuni caratteri non ASCII non sono codificati (come ä) in alcune impostazioni della lingua, forse aggiungi un export LC_ALL=Cnella funzione (che non dovrebbe influenzare nulla al di fuori della funzione)?
12431234123412341234123

8

Caratteri URI riservati con codifica percentuale e caratteri non ASCII

jq -s -R -r @uri

-s( --slurp) legge le righe di input in un array e -s -R( --slurp --raw-input) legge l'input in una singola stringa. -r(--raw-output ) genera il contenuto delle stringhe anziché i valori letterali delle stringhe JSON.

Codifica in percentuale tutti i caratteri

xxd -p|tr -d \\n|sed 's/../%&/g'

tr -d \\nrimuove gli avanzamenti riga che vengono aggiunti xxd -pdopo ogni 60 caratteri.

Codifica in percentuale tutti i caratteri tranne i caratteri alfanumerici ASCII in Bash

eu () {
    local LC_ALL=C c
    while IFS= read -r -n1 -d '' c
    do 
        if [[ $c = [[:alnum:]] ]]
        then 
            printf %s "$c"
        else
            printf %%%02x "'$c"
        fi
    done
}

Senza -d ''questo salterebbe avanzamenti di riga e byte null. Senza IFS=questo rimpiazzerebbe i personaggi IFScon %00. Senza LC_ALL=Cquesto, ad esempio, verrebbe sostituito con %3042in una locale UTF-8.


5

Pura soluzione bash solo per la decodifica :

$ a='%C3%A6ndr%C3%BCk'
$ echo -e "${a//%/\\x}"
ændrük

4

Non posso commentare sulla risposta migliore a questa discussione , ecco la mia.

Personalmente, utilizzo questi alias per la codifica e decodifica URL:

alias urlencode='python -c "import urllib, sys; print urllib.quote(  sys.argv[1] if len(sys.argv) > 1 else sys.stdin.read()[0:-1])"'

alias urldecode='python -c "import urllib, sys; print urllib.unquote(sys.argv[1] if len(sys.argv) > 1 else sys.stdin.read()[0:-1])"'

Entrambi i comandi consentono di convertire i dati, passati come argomento della riga di comando o di leggerli dall'input standard , poiché entrambi i caratteri di una riga controllano se esistono argomenti della riga di comando (anche vuoti) e li elaborano o semplicemente leggono l'input standard in altro modo.

aggiornamento 16/07/2015 (1 ° arg vuoto)

... secondo il commento di @muru.

aggiornamento 28-05-2017 (codifica barra)

Se è necessario codificare anche la barra, è sufficiente aggiungere un secondo argomento vuoto alla funzione quote, quindi verrà anche codificata la barra.

Quindi, finalmente l' urlencode alias in bash è simile al seguente:

alias urlencode='python -c "import urllib, sys; print urllib.quote(sys.argv[1] if len(sys.argv) > 1 else sys.stdin.read()[0:-1], \"\")"'

Esempio

$ urlencode "Проба пера/Pen test"
%D0%9F%D1%80%D0%BE%D0%B1%D0%B0%20%D0%BF%D0%B5%D1%80%D0%B0%2FPen%20test

$ echo "Проба пера/Pen test" | urlencode
%D0%9F%D1%80%D0%BE%D0%B1%D0%B0%20%D0%BF%D0%B5%D1%80%D0%B0%2FPen%20test

$ urldecode %D0%9F%D1%80%D0%BE%D0%B1%D0%B0%20%D0%BF%D0%B5%D1%80%D0%B0%2FPen%20test
Проба пера/Pen test

$ echo "%D0%9F%D1%80%D0%BE%D0%B1%D0%B0%20%D0%BF%D0%B5%D1%80%D0%B0%2FPen%20test" | urldecode
Проба пера/Pen test

$ urlencode "Проба пера/Pen test" | urldecode
Проба пера/Pen test

$ echo "Проба пера/Pen test" | urlencode | urldecode
Проба пера/Pen test

1
Penso che sys.argv[1] if len(sys.argv) > 1 else sys.stdin.read()[0:-1]potrebbe essere più appropriato. Soprattutto se lo usi negli script e accidentalmente fornisci un primo argomento vuoto.
muru,

Come da commento di @muru ho modificato il controllo di un argomento sulla riga di comando. Era: len(sys.argv) < 2 and sys.stdin.read()[0:-1] or sys.argv[1] Ora: sys.argv[1] if len(sys.argv) > 1 else sys.stdin.read()[0:-1] Cioè, se c'è anche un primo argomento vuoto, il comando non attende l'input dall'input standard, ma elabora un argomento vuoto.
DIG mbl

2

Ho trovato un pacchetto renameutilsche contiene l'utilità in deurlnamegrado di rinominare un file contenente caratteri "con codifica percentuale".

Sfortunatamente, non decodifica stdin o un'opzione della riga di comando, ma rinomina solo un file, quindi è necessario creare un file fittizio per ottenere la decodifica (il nome del file rinominato), ma con alcuni script bash il processo può essere automatizzato .

Nessuna informazione sulla parte di codifica, anche perché potrebbe essere discutibile quali caratteri codificare. Solo non ASCII?

Penso che ci dovrebbe essere uno strumento / metodo migliore.


1

Simile a Stefano Ansqer ma in Python 3:

python -c "import urllib.parse, sys; print(urllib.parse.quote(sys.argv[1]))" æ
python -c "import urllib.parse, sys; print(urllib.parse.unquote(sys.argv[1]))" %C3%A6

Per codificare anche le barre:

python -c "import urllib.parse, sys; print(urllib.parse.quote(sys.argv[1] if len(sys.argv) > 1 else sys.stdin.read()[0:-1], \"\"))"

Maggiori informazioni sulla differenza qui .


0

Ecco una funzione POSIX Awk per la codifica:

function encodeURIComponent(str, j, q) {
  while (y++ < 125) z[sprintf("%c", y)] = y
  while (y = substr(str, ++j, 1))
    q = y ~ /[[:alnum:]_.!~*\47()-]/ ? q y : q sprintf("%%%02X", z[y])
  return q
}

Esempio

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.