Odpowiedź
cat testfile | awk '{ print length, $0 }' | sort -n -s | cut -d" " -f2-
Lub, aby wykonać oryginalne (być może niezamierzone) sortowanie dowolnych równych długości wierszy:
cat testfile | awk '{ print length, $0 }' | sort -n | cut -d" " -f2-
W obu przypadkach rozwiązaliśmy zgłoszony problem, odsuwając się od awk do ostatecznego cięcia.
Linie o dopasowanej długości - co zrobić w przypadku krawata:
Pytanie nie określało, czy dalsze sortowanie było potrzebne dla wierszy o pasującej długości. Założyłem, że jest to niepożądane i zasugerowałem użycie -s
( --stable
), aby zapobiec sortowaniu takich wierszy względem siebie i utrzymywać je we względnej kolejności, w jakiej występują na wejściu.
(Ci, którzy chcą mieć większą kontrolę nad sortowaniem tych powiązań, mogą spojrzeć na --key
opcję sortowania ).
Dlaczego próba rozwiązania tego pytania zawodzi (przebudowa wiersza awk):
Warto zauważyć różnicę między:
echo "hello awk world" | awk '{print}'
echo "hello awk world" | awk '{$1="hello"; print}'
Dają odpowiednio
hello awk world
hello awk world
Odpowiedniej sekcji (gawk'S) instrukcja wspomina tylko na marginesie, że awk będzie odbudować całe $ 0 (na podstawie separatora, etc) w przypadku zmiany jednego pola. Myślę, że to nie jest szalone zachowanie. Ma to:
„Wreszcie są chwile, kiedy wygodnie jest zmusić awk do odbudowania całego rekordu przy użyciu bieżącej wartości pól i OFS. Aby to zrobić, użyj pozornie nieszkodliwego przypisania:”
$1 = $1 # force record to be reconstituted
print $0 # or whatever else with $0
„To zmusza awk do odbudowania rekordu”.
Wejście testowe zawierające kilka wierszy o równej długości:
aa A line with MORE spaces
bb The very longest line in the file
ccb
9 dd equal len. Orig pos = 1
500 dd equal len. Orig pos = 2
ccz
cca
ee A line with some spaces
1 dd equal len. Orig pos = 3
ff
5 dd equal len. Orig pos = 4
g