So erhalten Sie die kürzeste Zeichenfolge in einer Textdatei mit Shell

4243
SpawnST

Angenommen, ich habe eine Textdatei wie unten

abcd aaaaaaa gfgk hahahahahahhahh gf 

Dann gfwürde zurückgegeben werden. Irgendwelche guten Ideen?

3

5 Antworten auf die Frage

10
Bkkbrad

Awk ist dafür großartig:

awk '(NR == 1 || length < length(shortest)) { shortest = $0 } END { print shortest }' 

Der erste Teil setzt die "kürzeste" Variable auf die aktuelle Zeile, wenn es sich um die erste Zeile handelt oder wenn die Länge kürzer ist als die kürzeste zuvor gesehene Zeile. Der letzte Teil gibt schließlich den Wert von kürzester aus.

Ehrfürchtig, der Toolbox hinzugefügt. l0b0 vor 13 Jahren 0
7
nik

Angenommen, Ihre Zeilen enthalten ein "Wort" aus Zeichen,
und es macht uns nichts aus, wenn Sie die Shell etwas mehr arbeiten lassen.
Hier ist eine AWK-Lösung.

# Lassen Sie Ihren Text in `str.txt` stehen  awk '' str.txt | sort -nk 1 | Kopf -1  # Ausgabe: 2 gf ## Die kürzeste Zeichenfolge 

Sie können dies optimieren, um eine Sortierung mit mehr AWK zu vermeiden.
Sie können dies weiter anpassen, wenn Sie mehr als ein Wort pro Zeile haben.

Beachten Sie auch, dass Sie, wenn Sie mehrere kürzeste Zeichenfolgen haben, eine davon erhalten.
Du kannst noch ein paar Tricks machen, um sie zu bekommen.

Ich mag das, aber es sollte "$ 0" (vollständige Zeile) anstelle von "$ 1" (erstes Feld) verwenden. "$ 1" kehrt nur bis zum ersten Leerzeichen zurück. Das Beispiel von SpawnST enthält keine Leerzeichen, so dass es auch funktionieren würde, wenn seine reale Datendatei dieselbe ist. Doug Harris vor 14 Jahren 0
@Doug, ich beziehe mich auf den ersten Satz der Antwort :-) nik vor 14 Jahren 0
Ups, Entschuldigung, ich habe Ihre Vermutungslinie verpasst. Ich hatte deine Antwort sowieso schon positiv bewertet. Doug Harris vor 14 Jahren 0
3
Ignacio Vazquez-Abrams

Der BASH-FAQ- Eintrag Nr. 1 beschreibt, wie eine Datei Zeile für Zeile gelesen wird. ${#foo}wird dir die Länge von geben $foo. Führen Sie einfach eine Schleife aus und testen Sie jede Zeile nacheinander.

2
jfg956

Eine Lösung, die sed verwendet und die 1. kürzeste Zeile aus der Datei enthält:

sed -e '1h;H;g;s/[^\n]/#/g;s/\(#*\)\n\1/\n/;G;/^\n/s/\n.*\n\(.*\)\n.*/\1/;s/.*\n//;h;$!d' your_file 

So behalten Sie die letzte kürzeste Zeile der Datei:

sed -e '1h;G;h;s/[^\n]/#/g;s/\(#*\)\n\1/\n/;G;/^\n/s/\n.*\n\(.*\)\n.*/\1/;s/.*\n//;h;$!d' your_file 

Bellow ist eine erläuterte Version der 1. kürzesten Zeile in Form einer sed-Skriptdatei, die folgendermaßen ausgeführt werden kann sed -f script your_file:

# The hold space will contain the shortest line at the beginning and the ending of each cycle. # The 1st line is the shortest, so put it in the hold space so an empty line will not be returned. 1h # Append the current line to the shortest so far, remember these 2 lines in the hold space, and take a copy in the pattern space to work on them. H;g # Replace all chars by #. s/[^\n]/#/g # Delete the same number of # before and after the line delimiter. s/\(#*\)\n\1/\n/ # Append the 2 lines remembered in the hold space to the pattern space. G # If the hold space begin by a '\n', the current line was shorter, so keep it. /^\n/s/\n.*\n\(.*\)\n.*/\1/ # Else, the previous line was shorter, so keep it. s/.*\n// # Remember shortest in hold space. h # If last line, print it (delete everything else). $!d 
+1, wenn Sie sich dieses sed-Skript genau und lange genug ansehen, können Sie die Frau im roten Kleid sehen ... michael vor 10 Jahren 0
0
Paul-Gerhard Woolcock

Hier mein etwas ungeschicktes Angebot mit Perl:

grep . file | perl -E '@a=<>; @s = sort @a; say $s[0] . "Line $."; ' 

Etwas einfacher: perl -ne '$ l = $ _ if $. == 1; $ l = $ _ wenn Länge ($ ) <Länge ($ l); END 'file ### kürzeste Perl -ne' $ l = $ if $. == 1; $ l = $ _ wenn Länge ($ _)> Länge ($ l); END 'Datei ### am längsten

grep. Datei | perl -ne '$ l = $ _ wenn $. == 1; $ l = $ _ wenn Länge ($ _) <Länge ($ l); END '## kürzeste mögliche Leerzeilen entfernen

grep. Datei | perl -ne '$ l = $ _ wenn $. == 1; $ l = $ _ wenn Länge ($ _) <Länge ($ l); END '## möglichst lange Leerzeilen entfernen