回答
cat testfile | awk '{ print length, $0 }' | sort -n -s | cut -d" " -f2-
または、同じ長さの行の元の(おそらく意図しない)サブソートを行うには、次のようにします。
cat testfile | awk '{ print length, $0 }' | sort -n | cut -d" " -f2-
どちらの場合も、最終的なカットのためにawkから離れることで、指定された問題を解決しました。
長さが一致する線-引き分けの場合の処理:
質問では、長さが一致する行に対してさらにソートが必要かどうかは指定されていませんでした。これは望ましくないと想定し、-s
(--stable
)を使用して、このような行が互いに並べ替えられないようにし、入力で発生する相対的な順序でそれらを維持することを提案しました。
(これらのタイのソートをより細かく制御したい人は、ソートの--key
オプションを検討するかもしれません。)
質問の解決策が失敗する理由(awk行の再構築):
以下の違いに注意してください。
echo "hello awk world" | awk '{print}'
echo "hello awk world" | awk '{$1="hello"; print}'
彼らはそれぞれ降ります
hello awk world
hello awk world
(gawkの)マニュアルの関連セクションでは、1つのフィールドを変更すると、awkが$ 0全体(セパレーターなどに基づいて)を再構築することを余談として述べています。私はそれがクレイジーな振る舞いではないと思います。これには:
「最後に、フィールドとOFSの現在の値を使用して、awkにレコード全体を強制的に再構築させると便利な場合があります。これを行うには、一見無害な割り当てを使用します。」
$1 = $1 # force record to be reconstituted
print $0 # or whatever else with $0
「これにより、awkはレコードを再構築する必要があります。」
同じ長さのいくつかの行を含むテスト入力:
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