大きなファイルで2つの文字列を並べ替えることは可能ですか?
たとえば、現在のファイルは次のようになります。
0cf Front Brake
0d0 Rear Brake
0ce Handle Bars
HUT 03 VR Controls
009 Vest
001 Belt
002 Body Suit
020 Stereo Enable
003 Flexor
007 Hand Tracker
004 Glove
006 Head Mounted Display
008 Oculometer
00a Animatronic Device
000 Unidentified
021 Display Enable
005 Head Tracker
HUT 04 Sport Controls
000 Unidentified
002 Golf Club
001 Baseball Bat
希望の出力は次のとおりです。
0ce Handle Bars
0cf Front Brake
0d0 Rear Brake
HUT 03 VR Controls
000 Unidentified
001 Belt
002 Body Suit
003 Flexor
004 Glove
005 Head Tracker
006 Head Mounted Display
007 Hand Tracker
008 Oculometer
009 Vest
00a Animatronic Device
020 Stereo Enable
021 Display Enable
HUT 04 Sport Controls
000 Unidentified
001 Baseball Bat
002 Golf Club
ここでは、一部HUT 03 VR制御そしてHUT 04モーションコントロールすでに整理されています。
指定されたファイルでは、セクションタイトルはスペースではなく文字で始まり、セクションの内容は常にスペースまたはタブ文字で始まります。ファイルには100以上のセクションがあるため、スクリプト/コマンドでセクション名をハードコードすることはできません。
答え1
Pythonでは:
#!/usr/bin/python3
with open("file.txt", "r") as ins:
lines = []
for line in ins:
if line.startswith((" ", "\t")):
lines.append(line)
else:
lines.sort()
print(*lines, end = "", sep = "")
print(line, end = "")
lines = []
lines.sort()
print(*lines, end = "", sep = "")
これにより、特定の2行間のセクションだけでなく、すべてのセクションが(個別に)並べ替えられます。
答え2
$ awk 'BEGIN { OFS="\t"; s=0 } /^[^[:blank:]]/ { print ++s "\b", $0; next } { print s, $0 }' file | sort -n | cut -f 2-
0ce Handle Bars
0cf Front Brake
0d0 Rear Brake
HUT 03 VR Controls
000 Unidentified
001 Belt
002 Body Suit
003 Flexor
004 Glove
005 Head Tracker
006 Head Mounted Display
007 Hand Tracker
008 Oculometer
009 Vest
00a Animatronic Device
020 Stereo Enable
021 Display Enable
HUT 04 Sport Controls
000 Unidentified
001 Baseball Bat
002 Golf Club
これにより、awk
行セクションに対応する各行の前に数字(およびタブ区切り文字)が追加されます。セクションのタイトルには数字とバックスペース文字を追加します(バックスペースがタブの前にソートされるため)。次に、その数値の結果データを並べ替え、その数値と追加されたタブ区切り文字を削除します。
行の先頭で空白以外の文字を検索し、セクションのタイトルを検出します。
答え3
楽しみにして、以下を使用して単一のセクションを整列させる方法がありますex
。
ex file <<%
/HUT
+1,/HUT/-1!sort
w file.sorted
q
%
答え4
このような作業では、スクリプトが退屈だと思うことがよくあります。一度だけ実行し、いくつかのファイルに対してのみ実行する必要がある場合は、ファイルを開き、vim
次のように入力します。
GoFAKE SECTION<ESC>
:最後に偽のセクションを追加し、それが行の先頭にあることを確認してください(または有効にすることができますcindent
)autoindent
。これは、最後の部分をソートするためにも必要です。gg
:ファイルの先頭に戻り、1行下のセクションでファイルが起動します。j
qq
:q を登録するマクロ記録を開始します。v
:選択開始/^\S\+<Enter>
:次のセクションの先頭を検索します。k
:1行上に移動:!sort<Enter
: 部品の位置合わせnj
:次のセクションの最初の要素に移動q
: マクロ記録の停止@q
: マクロの繰り返し100@@
:マクロを数回繰り返します(残りの部分がないまで)。dd
:ファイルの最後の行を削除する(FAKE SECTION
)
:set lazyredraw
マクロの実行速度を上げたい場合があります。