|
X-DoSt-X
Anmeldungsdatum: 11. März 2010
Beiträge: 306
|
Hallo, ich brauche etwas, um doppelte Zeilen zu löschen. Eigentlich wäre sort -u genau das Richtige. Doch bricht der einfach so ab, wenn er auf einen Windows-Umlaut trifft. Gibt es noch etwas anderes? Kann ich ggf. alle möglichen Windows-Umlaute vorher in die entsprechenden Linux-Umlaute umwandeln?
|
|
sebix
Ehemalige
Anmeldungsdatum: 14. April 2009
Beiträge: 5584
|
Was ist der Unterschied zwischen einem Windows- und einem Linuxumlaut? Wenn es um Dateien geht: Um welche Encodings geht es? Kannst du dir mit zB file anzeigen lassen.
|
|
Seebär
Anmeldungsdatum: 2. Mai 2009
Beiträge: 833
|
Zum einen wird - wie in der Hilfe von sort angegeben - die locale eine Rolle spielen, somit ggf. LC_ALL=C sort ... verwenden, zum anderen, wie schon vorher bemerkt, ist das encoding vmtl. ebenso wichtig. Falls du Files konvertieren musst: icon nutzen. Ansonsten auch mal Problem klarer beschreiben.
|
|
seahawk1986
Anmeldungsdatum: 27. Oktober 2006
Beiträge: 11278
|
X-DoSt-X schrieb: Gibt es noch etwas anderes?
Gute Texteditoren - die können zum einen mit einstellbaren Encodings arbeiten und zum anderen bieten sie Funktionen zum Entfernen von doppelten Zeilen - man könnte z.B. den eingebauten sort-Befeh vom vim nutzen - der ex-Befehl für den Buffer wäre dann :sort u Bei Emacs >= 24.4 sollte es der Befehl M-x delete-duplicate-lines tun - die beiden Editoren gibt es nebenbei bemerkt auch für Windows.
|
|
X-DoSt-X
(Themenstarter)
Anmeldungsdatum: 11. März 2010
Beiträge: 306
|
Danke euch allen für eure Antworten. Hier eine genauere Beschreibung des Problems: die /etc/hosts Lange Zeit war es ganz einfach: verschiedene /etc/hosts runterladen (alle in einen Topf), danach sort -u → fertig ist meine /etc/hosts. (Jaaa, irgend wo wurden noch der Zeilenumbruch und andere Kleinigkeiten geändert.) Irgend wann fiel mir auf (vor 2…3 Jahren), dass die /etc/hosts jedoch immer kleiner wird, und irgendwie konnte ich mich mit der Einstellung: "Cool, immer mehr Bad-Hosts geben auf!" nicht so richtig abfinden. Ergebnis einer (jetzt erst) Fehlersuche: die Möglichkeit Umlaute in die HOST-Namen zu nehmen, wird auch von Bad-Hosts rege genutzt. Encodings weiß ich leider nicht (müsste das nicht im Kopf der Datei drinstehen?). Es sind alles Dateien mit 0D 0A als Zeilenumbruch. Daher meine Schlussfolgerung: Windows. Es handelt sich konkret um folgende vier Dateien: http://winhelp2002.mvps.org/hosts.txt
http://hosts-file.net/download/hosts.txt
http://someonewhocares.org/hosts/hosts
http://pgl.yoyo.org/as/serverlist.php?hostformat=hosts&showintro=1&mimetype=plaintext
|
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 13242
|
Dann ist natürlich das erste, was Du machst, sie mittels dos2unix o.ä. auf einheitliche Unix-Zeilenenden umzuwandeln. Dann würde ich vermutlich, wie schon erwähnt mit LOCALE=C sortieren. Also vielleicht so: | for url in http://winhelp2002.mvps.org/hosts.txt \
http://hosts-file.net/download/hosts.txt
do
curl -s "$url"
done | dos2unix | LOCALE=C sort -u >|/etc/hosts.new
|
|
|
kB
Supporter, Wikiteam
Anmeldungsdatum: 4. Oktober 2007
Beiträge: 9837
|
X-DoSt-X schrieb: […] /etc/hosts […] die Möglichkeit Umlaute in die HOST-Namen zu nehmen, wird auch von Bad-Hosts rege genutzt.
Du willst also vermutlich Deine Datei /etc/hosts missbrauchen um Werbung durch lokales DNS-Spoofing auszufiltern. In den im Internet verwendeten URLs wird zur Codierung von nicht-ASCII-Zeichen Punycode verwendet. Diese Codierung hat nichts mit der von MS-Windows verwendeten zu tun und auch nichts mit der bei einem Ubuntu-System verwendeten Codierung. Wenn Du das lokale DNS-Spoofing anwenden willst, darfst Du die Punycode-Bezeichnungen nicht konvertieren. Allerdings kann es sein, dass sie bereits durch die Webseiten, von denen Du sie bezogen hast, verhunzt (d.h. fälschlicherweise umcodiert) wurden. Webseiten verwenden natürlich (!) für den Inhalt wieder eine andere Codierung als die für Ihre URL, die auch verschieden sein kann als die von MS Windows oder Unix oder sonst wem verwendeten Code. Willkommen in der Schlangengrube!
|
|
seahawk1986
Anmeldungsdatum: 27. Oktober 2006
Beiträge: 11278
|
Ich würde mich da nicht mit der Bash aufhalten:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 | #!/usr/bin/env python3
import concurrent.futures
import re
import requests
COMMENT_RE = "\s+#.*$"
URLS=[
"http://winhelp2002.mvps.org/hosts.txt",
"http://hosts-file.net/download/hosts.txt",
"http://someonewhocares.org/hosts/hosts",
"http://pgl.yoyo.org/as/serverlist.php?hostformat=hosts&showintro=1&mimetype=plaintext",
]
hosts = set()
def clean_data(data):
for line in data.splitlines():
line = line.strip()
if not line.startswith('#'):
line = re.sub(COMMENT_RE,'', line)
yield line
with concurrent.futures.ThreadPoolExecutor() as executor:
future_to_url = {executor.submit(requests.get, url): url for url in URLS}
for future in concurrent.futures.as_completed(future_to_url):
url = future_to_url[future]
try:
data = future.result().text
except Exception as exc:
print('%r generated an exception: %s' % (url, exc))
else:
hosts.update(set(clean_data(data)))
with open('hosts', 'w') as f:
f.write('\n'.join(sorted(hosts)))
|
Da die von dem Python-Skript erzeugte Datei hosts ohne Probleme von sort -u verarbeitet wird (wobei sie selbst schon sortiert ist und aus einzigartigen Zeilen besteht), scheint es in den URLs aus den heruntergeladenen Hostdateien selbst keine störenden Zeichen zu geben.
|
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 13242
|
seahawk1986 schrieb: Ich würde mich da nicht mit der Bash aufhalten:
Hm, 7 gegen 36 Zeilen. Gut, das Python-Programm holt die Daten parallel, aber das bekommt man auch mit relativ wenig Aufwand mit parallel und meinem Skript hin. Schicker ist natürlich die Lösung in Python...
|
|
seahawk1986
Anmeldungsdatum: 27. Oktober 2006
Beiträge: 11278
|
rklm schrieb: Hm, 7 gegen 36 Zeilen.
Man kann das auch in deutlich weniger Zeilen machen, wenn man es darauf anlegt... - hier mal mit unter 100 Zeichen pro Zeile:
1
2
3
4
5
6
7
8
9
10
11
12
13
14 | #!/usr/bin/env python3
import concurrent.futures, re, requests
URLS=["http://winhelp2002.mvps.org/hosts.txt",
"http://hosts-file.net/download/hosts.txt",
"http://someonewhocares.org/hosts/hosts",
"http://pgl.yoyo.org/as/serverlist.php?hostformat=hosts&showintro=1&mimetype=plaintext"]
hosts = set()
with concurrent.futures.ThreadPoolExecutor() as executor:
future_to_url = {executor.submit(requests.get, url): url for url in URLS}
for fut in concurrent.futures.as_completed(future_to_url):
try: hosts.update(set(re.sub("\s+#.*$", '', l) for l in (
l.strip() for l in fut.result().text.splitlines()) if (l and not l.startswith('#'))))
except Exception as exc: print('%r generated an exception: %s' % (future_to_url[fut], exc))
with open('hosts', 'w') as f: f.write('\n'.join(sorted(hosts)))
|
Der Grund weshalb ich bei curl vorsichtig bin ist ein anderer - das schreibt die heruntergeladenen Daten soweit ich weiß unverändert raus - wenn eine der Urls keine in ASCII bzw. UTF-8 encodierten Daten ausliefern würde (also tatsächlich sowas wie iso-8859-15 als Encoding genutzt werden würde), hätte man das Problem, dass man einen Mix aus unterschiedlich encodierten Zeilen in der resultierenden Datei bekommt. Das requests-Modul versucht das Encoding aus dem vom Server für den Request gesendeten Header abzuleiten - falls das automatische Decoding nicht klappt, gibt es eine entsprechende Fehlermeldung (dann könnte man für eine Antwort von einer bestimmten URL das Encoding vorgeben) und es sollte immer nur UTF-8 encodierter Text in der Ausgabedatei landen.
|
|
frostschutz
Anmeldungsdatum: 18. November 2010
Beiträge: 7795
|
X-DoSt-X schrieb: Es handelt sich konkret um folgende vier Dateien:
Ungültige Zeichen kannst du z.B. mit iconv finden. $ iconv -f ascii -t utf-8 < hosts.txt | tail
iconv: illegal input sequence at position 17997931
127.0.0.1 www.huala "aussteigen" tut sort deswegen bei mir allerdings nicht.
|
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 13242
|
seahawk1986 schrieb:
Der Grund weshalb ich bei curl vorsichtig bin ist ein anderer - das schreibt die heruntergeladenen Daten soweit ich weiß unverändert raus - wenn eine der Urls keine in ASCII bzw. UTF-8 encodierten Daten ausliefern würde (also tatsächlich sowas wie iso-8859-15 als Encoding genutzt werden würde), hätte man das Problem, dass man einen Mix aus unterschiedlich encodierten Zeilen in der resultierenden Datei bekommt. Das requests-Modul versucht das Encoding aus dem vom Server für den Request gesendeten Header abzuleiten - falls das automatische Decoding nicht klappt, gibt es eine entsprechende Fehlermeldung (dann könnte man für eine Antwort von einer bestimmten URL das Encoding vorgeben) und es sollte immer nur UTF-8 encodierter Text in der Ausgabedatei landen.
rklm schrieb:
Schicker ist natürlich die Lösung in Python...
☺
|