Wie kann ich prozentual codierte Zeichenfolgen in der Befehlszeile codieren und decodieren?

31

Wie kann ich prozentual codierte (URL-codierte) Zeichenfolgen in der Befehlszeile codieren und decodieren ?

Ich bin auf der Suche nach einer Lösung, die dies ermöglicht:

$ percent-encode "ændrük"
%C3%A6ndr%C3%BCk
$ percent-decode "%C3%A6ndr%C3%BCk"
ændrük
ændrük
quelle
Möchten Sie auch verschiedene Kodierungen einbinden? %E6ndr%FCksieht für mich nicht wie (Standard) UTF8 aus. Oder ist es nur ein Beispiel?
Ordnen Sie den
@arrange Danke, dass du das erwischt hast. Anscheinend habe ich den schlechten Apfel unter den Suchergebnissen für Online-Konverter ausgewählt.
ændrük
Informationen zu Dateinamen finden Sie unter: So entfernen Sie die URI-Codierung in Dateinamen .
Kenorb

Antworten:

35

Diese Befehle machen was Sie wollen:

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

Wenn Sie Leerzeichen als kodieren möchten +, ersetzen Sie urllib.quotedurch urllib.quote_plus.

Ich nehme an, du willst sie aliasen ;-)

Stefano Palazzo
quelle
1
Was ist das æ Zeichen am Ende der ersten Zeile? Edit: antworte mir selbst - verstehe, es ist nur ein einzelnes Zeichen UTF8 codiert werden Zeichenfolge zum Beispiel Zweck :-)
TMG
1
Wie wäre es mit Python3?
RicardoE
@ RicardoE überprüfen Sie diese Antwort .
Pablo A
27

Schale

Versuchen Sie die folgende Befehlszeile:

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

Sie können es als Alias ​​definieren und zu Ihren Shell- RC- Dateien hinzufügen :

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

Dann gehen Sie jedes Mal, wenn Sie es brauchen, einfach mit:

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

Bash

Bei der Skripterstellung können Sie die folgende Syntax verwenden:

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

Die obige Syntax behandelt Pluszeichen ( +) jedoch nicht korrekt, sodass Sie sie durch Leerzeichen über ersetzen müssen sed.

Sie können auch die folgende verwenden urlencode()und urldecode()Funktionen:

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}"
}

Beachten Sie, dass Ihr urldecode () davon ausgeht, dass die Daten keinen Backslash enthalten.


bash + xxd

Bash-Funktion mit xxdTool:

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
}

Gefunden in der Hauptdatei von cdown , auch bei stackoverflow .


Python

Versuchen Sie, die folgenden Aliase zu definieren:

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])"'

Verwendung:

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

Quelle: Ruslanspivak


PHP

Mit PHP können Sie den folgenden Befehl versuchen:

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

oder nur:

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

Verwendung -Rfür mehrzeilige Eingabe.


Perl

In Perl können Sie verwenden URI::Escape.

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

Oder um eine Datei zu verarbeiten:

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

sed

Verwendung sedkann erreicht werden durch:

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

awk

Versuchen Sie eine andere Lösung:

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

Siehe: Verwenden von awk printf zum URL-Code von Text .


Dateinamen entschlüsseln

Wenn Sie die URL-Codierung aus den Dateinamen entfernen müssen, verwenden Sie das deurlnameTool von renameutils(z deurlname *.*. B. ).

Siehe auch:


Verbunden:

Kenorb
quelle
Die bash + xxd Version funktioniert nicht mit Zeichenfolgen , die ein enthalten %, vielleicht könnten Sie ersetzen printf "$c"mit printf "%c" "$c"? Ein weiteres Problem besteht darin, dass einige Nicht-ASCII-Zeichen äin einigen Spracheinstellungen nicht codiert sind (z. B. ). Fügen Sie möglicherweise ein export LC_ALL=Cin die Funktion ein (das sollte nichts außerhalb der Funktion beeinflussen).
12431234123412341234123
8

Prozentcodierte reservierte URI-Zeichen und Nicht-ASCII-Zeichen

jq -s -R -r @uri

-s( --slurp) liest Eingabezeilen in ein Array und -s -R( --slurp --raw-input) liest die Eingabe in eine einzelne Zeichenfolge. -r( --raw-output) gibt den Inhalt von Strings anstelle von JSON-String-Literalen aus.

Prozentcodierung aller Zeichen

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

tr -d \\nEntfernt die Zeilenvorschübe, die xxd -pnach jeweils 60 Zeichen hinzugefügt werden .

Prozentcodierung aller Zeichen außer alphanumerischen ASCII-Zeichen 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
}

Ohne -d ''dies würden Zeilenvorschübe und Null-Bytes übersprungen. Ohne IFS=dies würde Zeichen in IFSmit ersetzen %00. Ohne LC_ALL=Cdies beispielsweise ersetzen würde mit %3042in einer UTF-8 locale.

Nisetama
quelle
5

Reine Bash-Lösung nur zum Dekodieren :

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

Ich kann die beste Antwort in diesem Thread nicht kommentieren , also hier meine.

Persönlich verwende ich diese Aliase für die URL-Codierung und -Decodierung:

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])"'

Mit beiden Befehlen können Sie Daten konvertieren, die als Befehlszeilenargument übergeben oder von der Standardeingabe gelesen wurden , da beide Einzeilen prüfen, ob Befehlszeilenargumente (auch leere) vorhanden sind, und diese verarbeiten oder die Standardeingabe einfach anderweitig lesen.

Update 16.07.2015 (leeres 1. Argument)

... laut @muru-Kommentar.

Update 28.05.2017 (Schrägstrichcodierung)

Wenn Sie auch den Schrägstrich codieren müssen, fügen Sie der Anführungszeichenfunktion einfach ein leeres zweites Argument hinzu. Der Schrägstrich wird dann ebenfalls codiert.

Der urlencode Alias in der Bash sieht also so aus:

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

Beispiel

$ 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
DIG mbl
quelle
1
Ich denke, sys.argv[1] if len(sys.argv) > 1 else sys.stdin.read()[0:-1]könnte angemessener sein. Vor allem, wenn Sie dies in Skripten verwenden und versehentlich ein leeres erstes Argument angeben.
Muru
Gemäß @muru-Kommentar habe ich die Überprüfung auf ein Argument in der Befehlszeile geändert. Es war: len(sys.argv) < 2 and sys.stdin.read()[0:-1] or sys.argv[1] Now: sys.argv[1] if len(sys.argv) > 1 else sys.stdin.read()[0:-1] Das heißt, wenn es überhaupt ein leeres erstes Argument gibt, wartet der Befehl nicht auf die Eingabe von der Standardeingabe, sondern verarbeitet ein leeres Argument.
DIG mbl
2

Ich habe ein Paket gefunden, renameutilsdas das Hilfsprogramm enthält, mit dem deurlnameeine Datei mit "prozentcodierten" Zeichen umbenannt werden kann.

Leider wird weder stdin noch eine Befehlszeilenoption dekodiert, sondern nur eine Datei umbenannt. Sie müssen daher eine Dummy-Datei erstellen, um die Dekodierung (den Namen der umbenannten Datei) zu erhalten. Mit einigen Bash-Skripten kann der Vorgang jedoch automatisiert werden .

Keine Informationen zum Codierungsteil, auch wenn fraglich ist, welche Zeichen codiert werden sollen. Nur Nicht-ASCII?

Ich denke, es sollte ein besseres Werkzeug / eine bessere Methode geben.

Enzotib
quelle
1

Ähnlich wie Stefano ansqer, aber 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

So kodieren Sie auch Schrägstriche:

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

Mehr Infos zum Unterschied hier .

Pablo A
quelle
0

Hier ist eine POSIX Awk-Funktion zum Codieren:

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
}

Beispiel

Steven Penny
quelle