matze31
Anmeldungsdatum: 25. Oktober 2015
Beiträge: 729
|
Ich hoffe ich bin hier richtig.
Eine Frage an den Spezialisten: Kann man mit dem Befehl 'sort' auch bestimmte Zeilenabschnitte die doppelt sind rauskopieren?
Z.B. wenn ich eine Datei mit Zahlenreihe hab wie: 22444555667788
22444555666777
221155778899765
345666777888 Kann ich den 'sort' sagen,dass er nur auf die ersten 4 Zahlen "gucken" soll und wenn da etwas gleich ist, wird die
Zeile nicht doppelt in die neue Datei Kopiert. Sortieren mit Doppelten Zeilen sieht bei mir jetzt so aus:
"cat /home/Dokumente/mein.txt | sort -u >> /home/Dokumente/datei1.txt" Das klappt wunderbar.
Gibt es eine Möglichkeit? Bearbeitet von rklm: Codeblock. Bitte nutze doch die Möglichkeiten der Forum/Syntax!
|
track
Anmeldungsdatum: 26. Juni 2008
Beiträge: 7174
Wohnort: Wolfen (S-A)
|
Ja. Du kannst den Betrachtungsbereich einschränken, wie es auch in man sort steht. (→ genauere Erläuterungen gibt Dir info sort unter der Option -k) track@track:~$ sort -u testreihe.txt
221155778899765
22444555666777
22444555667788
345666777888
track@track:~$ sort -k1.1,1.5 -u testreihe.txt
221155778899765
22444555667788
345666777888 Es wird schön brav nur die 1. vorkommende Zeile ausgegeben. LG, track
|
matze31
(Themenstarter)
Anmeldungsdatum: 25. Oktober 2015
Beiträge: 729
|
Danke.
Und wie sieht dann der Befehl aus, wenn die ersten 16 Zahlen gleich sein dürfen und ab der 17. Zahl wird die Zeile nicht doppelt mit rüber
genommen?
Danke schon im Vorraus
|
stfischr
Anmeldungsdatum: 1. März 2007
Beiträge: 19197
|
Hi. Kombiniere geschickt head -n 16 und tail -n +17 sowie > (in Datei umleiten) >> (an Datei anhängen).
|
matze31
(Themenstarter)
Anmeldungsdatum: 25. Oktober 2015
Beiträge: 729
|
@stfischr Kannst du bitte mal eine Musterzeile schreiben:
Ich bin leider noch nicht so fit.
|
stfischr
Anmeldungsdatum: 1. März 2007
Beiträge: 19197
|
Ich denke mal, du hast verstanden, was deine Befehlszeile macht und was das | bedeutet? Du kannst also beliebig viele Befehle aneinanderreihen. Und am Ende in eine Datei schreiben (> Datei.txt) Deine Befehle müssen also folgendes machen:
gib mir die ersten 16 Zeilen der Datei Input.txt übergib (|) sie an sort (mit deiner gewünschten Option (-u oder kein -u)) schreibe sie in Datei Output.txt
Und den 2. Befehl für die restlichen Zeilen müsstest du dann auch ganz einfach hinbekommen. Nachher kommt die Lösung, überlege ruhig mal n paar Minuten.
|
track
Anmeldungsdatum: 26. Juni 2008
Beiträge: 7174
Wohnort: Wolfen (S-A)
|
Mit einer Musterdatei habe ich auch mal was gebastelt ... 😀 : | sort -u rand.txt | head -8 > rand.head # Datei mit den ersten 8 Voll-Treffern erzeugen
grep -vFf rand.head rand.txt | sort -uk1.1,1.4 | cat rand.head - # 1) die Zahlen dieser Kopfdatei 'rausfiltern
# 2) Teil-sortieren wie oben vorgeschlagen
# 3) zusammenführen der Kopfdatei mit der 2. Sortierliste
|
Das ist jetzt natürlich die direkte Kurzfassung. - Du solltest aber unbedingt nachlesen, was die Befehle genau machen, damit Dich nichts böse überrascht. (→ man - pages) LG, track
|
stfischr
Anmeldungsdatum: 1. März 2007
Beiträge: 19197
|
Uh? Da hatte ich einen Denkfehler. Geht gar nicht mit 2 Zeilen wie ich wollte. Mann muss ja erst alles sortieren 😳 Ich hätte an sowas gedacht:
sort input.txt > temp.txt
head -n 16 temp.txt > output.txt
tail -n +17 temp.txt | uniq >> output.txt
Was 16 vom Input nimmt (Mehrfache mitgezählt) und dann den Rest (sort -u garnicht nötig → uniq) ausfiltert und anhängt. Manchmal hat man dann aber noch einen 17. Mehrfachen. Müsste aber dann mit head 15 und tail +16 funktionieren? @track: kannst du dein grep mal erklären? Ich schnalls nicht. Oder verstehe ich das Problem falsch?
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17552
Wohnort: Berlin
|
Ich glaube Ihr redet aneinander vorbei. Er redet von Zahlen (gemeint sind offenbar Ziffern), Ihr zum Teil von Zeilen (head/tail).
|
track
Anmeldungsdatum: 26. Juni 2008
Beiträge: 7174
Wohnort: Wolfen (S-A)
|
stfischr schrieb: @track: kannst du dein grep mal erklären?
Na ja, da war ich mal wieder ganz besonders pingelig ... 😉 grep -v -F -f rand.head rand.txt
# | | | \ von dieser Datei
# | | \ hol die Suchbegriffe aus dieser Datei
# | \ suche mit genauem Text statt mit Regex
# \ invertiere die Suche: alle Zeilen, die nicht dem Suchkriterium entsprechen Streng genommen muss man die Option -x sogar auch noch dazu tun. (dass die ganze Zeile mit dem Suchbegriff übereinstimmt) Da hatte ich etwas gepennt. (sonst würde nämlich ein Teilstring irgendwo in der Zahl schon einen Treffer liefern !) Konkret am Beispiel: track@track:~$ echo '123456
123
0129456
1.
2345
341567
7654123
19' > rand.txt
track@track:~$ sort -u rand.txt | head -3 > rand.head
track@track:~$ cat rand.head # Inhalt der Kopf-Datei: (= Ausschluss-Liste)
0129456
1.
123
track@track:~$ grep -vf rand.head rand.txt
2345 # ... upps, da fehlt ja wohl was
track@track:~$ grep -vFf rand.head rand.txt
2345
341567 # diese passten nämlich auf das Reguläre Muster "1."
19 # -> also RE's ausschließen.
track@track:~$ grep -vxf rand.head rand.txt
123456 # Teilstrings sind jetzt unschädlich ...
2345
341567
7654123 # aber "19" fehlt: wird von "1." als RE fälschlich mit erfasst
track@track:~$ grep -vFxf rand.head rand.txt
123456
2345
341567
7654123
19 # erst hier ist alles komplett Das mal als Beispiel. Die Referenz dazu steht in man grep ... LG, track
|
stfischr
Anmeldungsdatum: 1. März 2007
Beiträge: 19197
|
user_unknown schrieb: Ich glaube Ihr redet aneinander vorbei. Er redet von Zahlen (gemeint sind offenbar Ziffern), Ihr zum Teil von Zeilen (head/tail).
Ahh ich sehe, und einfach die zu langen Zahlen vorher abschneiden? Mit cut oder so? Edit: Ah und jetzt verstehe ich auch tracks Lösung.
|
track
Anmeldungsdatum: 26. Juni 2008
Beiträge: 7174
Wohnort: Wolfen (S-A)
|
stfischr schrieb: Ich hätte an sowas gedacht:
sort input.txt > temp.txt
head -n 16 temp.txt > output.txt
tail -n +17 temp.txt | uniq >> output.txt
Das geht natürlich auch. Allerdings solltest Du noch 2 Kleinigkeiten ändern: sort -u input.txt > temp.txt # sonst hast Du evt. Doubletten in den ersten 16
head -n 16 temp.txt > output.txt
tail -n +17 temp.txt | uniq -w5 >> output.txt # mit dieser Option kann uniq das auch ... Der wichtigste Unterschied zwischen Deinem und meinem Ansatz ist, dass meiner den ersten Treffer und Deiner den kleinsten aller Mehrfachtreffer liefert. (durch das Vorsortieren) Was jetzt besser ist, hängt von den Daten ab ...
track@track:~$ echo '1
xxx4
xxx3
xxx2
5
6' | sort -uk1.1,1.3
1
5
6
xxx4
track@track:~$ echo '1
xxx4
xxx3
xxx2
5
6' | sort | uniq -w 3
1
5
6
xxx2 LG, track
p.s.: Meine Variante kann man auch noch ein bisschen streamlinen: 🐸 (dann braucht man nicht mal mehr eine Zwischendatei)
track@track:~$ echo '123
234
345
456
124
231
134' > rand.txt
track@track:~$ sort -u rand.txt | head -3 > rand.out
track@track:~$ cat rand.out # hier ist der Kopf:
123
124
134
track@track:~$ grep -vFxf rand.out rand.txt | sort -uk1.1,1.2 >> rand.out # so kann man die selbe Datei tatsächlich
track@track:~$ cat rand.out # zuerst lesen und dann weiter schreiben
123
124 # im Kopf bleiben die Teil-Doubletten erhalten
134
234
345 # im 2.Teil nicht, es kommt nur der 1.Treffer
456
|
matze31
(Themenstarter)
Anmeldungsdatum: 25. Oktober 2015
Beiträge: 729
|
Erstmal großes Danke schön für die Arbeit,
Nur ich hab das alles mal probiert. eventuell habe ich mich falsch ausgedrückt. Ich meinte wenn ich eine Datei mit z.b. 1000 Zeilen hab, und es befinden sich in den Zeilen Zahlen und Bchstaben.
Z.B. 1345333444112233446788643345
2458753859547694759474947597
2356456764112233448787689533
1233457978668765655655656565
9757657698112233449865967865
1344374565112233449853355555
2244354456445566775948495554
2346544679445566779875578444
.
.
. Hier in meinen Beispiel sind die 1.,5.,6. und die 7. und 8.Zeile von der 11. bis 18. Zahl gleich.
Darum gehts, wenn ich eine Datei mit "sort -u" kopiere, soll (wenn die 11. bis 18. Zahl gleich ist), sie alls doppelt ansehen und nur 1x kopieren.
Ziel ist es, dass dann nur noch die Zeilen übrig bleiben.
1345333444112233446788643345
2458753859547694759474947597
2356456764112233448787689533
1233457978668765655655656224
4354456445566775948495554565 Das ist nur eine Beispiel, denn ich kenne im Vorfeld die 11. bis zur 18. Zahl nicht.
Ist es möglich, dem "sort -u" zu sagen, er soll auf die 11. bis 18. Zahl schauen, und wenn die Zahlen/Buchstaben identisch sind, nimmt er sie nicht mit rüber?
LG
|
track
Anmeldungsdatum: 26. Juni 2008
Beiträge: 7174
Wohnort: Wolfen (S-A)
|
Das was Du da suchst, scheint uniq zu sein ... guck Dir bitte mal man uniq genauer an ! Damit er auch alle doppelten / mehrfachen erkennt, muss man die Liste vorher sortieren. In Deinem Fall wird man dabei natürlich beide Befehle auf die Spalten 11..18 beschränken. Aber damit geht das sehr wohl: track@track:~$ echo '1345333444112233446788643345
2458753859547694759474947597
2356456764112233448787689533
1233457978668765655655656565
9757657698112233449865967865
1344374565112233449853355555
2244354456445566775948495554
2346544679445566779875578444' | sort -k1.11,1.18 | uniq -s11 -w7
1344374565112233449853355555
2244354456445566775948495554
2458753859547694759474947597
1233457978668765655655656565 Durch das vorher sortieren gibt er in diesem Fall natürlich immer die niedrigste Zahl aus, nicht die erste. (Wenn sowas wichtig wäre, müsste man das ggf. per Hand selber programmieren, z.B. mit awk ) Überhaupt: was für Daten sind das eigentlich, und was willst Du am Ende damit machen ? - vielleicht ergeben sich ja daraus noch ganz andere Ansätze ? LG, track
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 12822
|
matze31 schrieb:
Ich meinte wenn ich eine Datei mit z.b. 1000 Zeilen hab, und es befinden sich in den Zeilen Zahlen und Bchstaben.
Z.B. 1345333444112233446788643345
2458753859547694759474947597
2356456764112233448787689533
1233457978668765655655656565
9757657698112233449865967865
1344374565112233449853355555
2244354456445566775948495554
2346544679445566779875578444
.
.
.
Ich sehe da keine Buchstaben.
Hier in meinen Beispiel sind die 1.,5.,6. und die 7. und 8.Zeile von der 11. bis 18. Zahl gleich.
Darum gehts, wenn ich eine Datei mit "sort -u" kopiere, soll (wenn die 11. bis 18. Zahl gleich ist), sie alls doppelt ansehen und nur 1x kopieren.
Ziel ist es, dass dann nur noch die Zeilen übrig bleiben.
1345333444112233446788643345
2458753859547694759474947597
2356456764112233448787689533
1233457978668765655655656224
4354456445566775948495554565 Das ist nur eine Beispiel, denn ich kenne im Vorfeld die 11. bis zur 18. Zahl nicht.
Ist es möglich, dem "sort -u" zu sagen, er soll auf die 11. bis 18. Zahl schauen, und wenn die Zahlen/Buchstaben identisch sind, nimmt er sie nicht mit rüber?
Ja, siehe unten. track schrieb: Das was Du da suchst, scheint uniq zu sein ... guck Dir bitte mal man uniq genauer an !
Das geht auch mit sort alleine: | $ cat x
ccc222
aaa111
bbb111
$ sort -suk 1.4n x
aaa111
ccc222
|
Durch das vorher sortieren gibt er in diesem Fall natürlich immer die niedrigste Zahl aus, nicht die erste. (Wenn sowas wichtig wäre, müsste man das ggf. per Hand selber programmieren, z.B. mit awk )
Auch nicht: dafür kann man die Option -s nehmen. 1
2
3
4
5
6
7
8
9
10
11
12
13
14 | $ sort -sunk 1.11,1.18 <<'DATA'
1345333444112233446788643345
2458753859547694759474947597
2356456764112233448787689533
1233457978668765655655656565
9757657698112233449865967865
1344374565112233449853355555
2244354456445566775948495554
2346544679445566779875578444
DATA
1345333444112233446788643345
2244354456445566775948495554
2458753859547694759474947597
1233457978668765655655656565
|
Das Ergebnis ist allerdings anders, als oben beschrieben. Ist das jetzt nur ein Versehen Deinerseits oder gibt es weitere Bedingungen, die noch nicht genannt wurden?
|