2009-10-21 3 views
10

Buduję małe narzędzie, które będzie pobierać pliki za pomocą wget, czytając adresy URL z różnych plików. Ten sam URL może występować w różnych plikach; adres URL może występować nawet w jednym pliku kilka razy. Byłoby nieefektywne, aby pobrać stronę kilka razy (za każdym razem, gdy jej adres znajduje się na liście).Jak obliczyć hash dla ciągu (url) w bash dla buforowania wget

Tak więc, prostym podejściem jest zapisanie pobranego pliku i polecenie, aby go nie pobrać ponownie, jeśli już jest.

To byłoby bardzo proste; jednak adresy URL są bardzo długie (wiele parametrów GET) i dlatego nie mogą być używane jako takie w nazwach plików (wget podaje za długi błąd "Nie można napisać do ... []").

Potrzebuję zmienić nazwę pobranych plików. Ale aby mechanizm buforowania działał, schemat zmiany nazwy musi zaimplementować "jeden URL < => jedna nazwa": jeśli dany adres URL może mieć wiele nazw, buforowanie nie działa (tj. Jeśli po prostu po prostu numery plików w kolejności zostaną znalezione, nie pozwolę wget zidentyfikować, które adresy zostały już pobrane).

Najprostszy schemat zmiany nazwy byłoby obliczyć hash md5 nazwy pliku (i nie samego pliku, który właśnie robi md5sum); to zapewniłoby, że nazwa pliku jest unikatowa i że dany adres URL zawsze będzie zawierał taką samą nazwę.

Można to zrobić w Perlu itp., Ale czy można to zrobić bezpośrednio w bashu lub przy użyciu narzędzia systemowego (RedHat)?

Odpowiedz

24

Wygląda na to, że chcesz użyć narzędzia systemowego md5sum.

URLMD5=`/bin/echo $URL | /usr/bin/md5sum | /bin/cut -f1 -d" "` 

Jeśli chcesz tylko utworzyć skrót na pliku, można uzyskać tak szybko z sed:

FILENAME=`echo $URL | /bin/sed -e 's#.*/##'` 
URLMD5=`/bin/echo $FILENAME | /usr/bin/md5sum | /bin/cut -f1 -d" "` 
+0

Więc wielkie dzięki za szybką odpowiedź; w Nie zdawałem sobie sprawy, że mogę po prostu użyć md5sum w ten sposób! Nie rozumiem, co mówisz o "nazwie pliku" jednak: kiedy klucz md5 jest obliczany, nie ma jeszcze nazw plików ...? – Bambax

+0

@bambax: Epsilon Prime odnosi się do części pliku adresu URL, na przykład: "index.html". Polecenie "sed" usuwa wszystko, włącznie z ostatnim ukośnikiem. –

+0

@Dennis: Ok, dzięki; ale w takim przypadku na pewno nie chcę po prostu używać nazwy pliku jako części adresu URL, ponieważ różne zestawy parametrów GET powinny powodować buforowanie/pobieranie różnych plików. – Bambax

1

Nowsze wersje Bash dostarczyć tablicę asocjacyjną, jak również tablicy indeksowanej. Coś takiego może pracować dla Ciebie:

declare -A myarray 
myarray["url1"]="url1_content" 
myarray["url2"]="" 

if [ ! -z ${myarray["url1"]} ] ; then 
    echo "Cached"; 
fi 

wget zazwyczaj nazwy plików z filename.html.1, .2, itp, więc można użyć tablicy asocjacyjnej do przechowywania listy z których jeden ma został pobrany i jaka była faktyczna nazwa pliku.

8

Nie mam przedstawiciela do komentowania odpowiedzi, ale jest jedno wyjaśnienie do odpowiedzi Epsilon Prime: domyślnie echo wypisze znak nowej linii na końcu tekstu. Jeśli chcesz sumy MD5 aby dopasować się z tym, co zostanie wygenerowany przez jakiekolwiek inne narzędzie (np php, MD5 Java, itp) trzeba zadzwonić

echo -n "$url" 

które będą tłumić przełamane.

+0

To naprawdę dziwna sprawa. Cieszę się, że teraz o tym wiem. – buildsucceeded

3

Inne opcje na moim Ubuntu (dokładne) pudełka:

  • echo -n $STRING | sha512sum
  • echo -n $STRING | sha256sum
  • echo -n $STRING | sha224sum
  • echo -n $STRING | sha384sum
  • echo -n $STRING | sha1sum
  • echo -n $STRING | shasum

Inne opcje na moim Macu:

  • echo -n $STRING | shasum -a 512
  • echo -n $STRING | shasum -a 256
  • itp