2012-01-30 16 views
5

Ho appena scoperto il comando :sort n in vim (come facevo a non saperlo ?!), che ha quasi fatto esattamente ciò di cui ho bisogno.Ordinamento degli indirizzi IP in vim

Quello che sto cercando di ordinare, però, è una lunga lista di indirizzi IP (è un file "permetti host" per essere Include d nella nostra configurazione di apache), e sarebbe bello per :sort n essere in grado di riconoscere che 123.45.6.7 debba essere ordinato prima di 123.45.16.7 (ad esempio).

E 'un presupposto sicuro che dovrei essere meno OCD su di esso e non preoccuparsi, perché io non ho intenzione di essere in grado di fare questo senza un eufemismo complesso sed o awk comando o qualcosa del genere?

Per essere chiari, le righe sembrano tutti qualcosa di simile:

Allow from 1.2.3.4 
Allow from 5.6.7.8 
Allow from 9.10.11.12 

ecc

risposta

8

Vim sembra essere praticamente stabile (ma non è garantito). Pertanto si può provare:

:%sort n /.*\./ 
:%sort n /\.\d\+\./ 
:%sort n /\./ 
:%sort n 

Quale sarà ordinare per numero dopo l'ultimo punto (* è avido), poi dal numero dopo il primo punto dopo un punto e le cifre, poi dal numero dopo il primo punto, e l'ultimo dal primo numero.

+0

Quasi completamente perfetto (e l'unica ragione per cui non era perché non avevo menzionato che alcune delle mie file erano maschere di rete). Grazie; questo mi ha fatto abbastanza lontano da ordinare le maschere di rete da me stesso. –

+1

Tramite pipe puoi eseguire tutto in una volta sola: ':% sort n /.*\./ | % sort n /\.\d\+\./ | % ordina n /\./ | % ordina n' – azzid

0

Io non sono un utente vim, quindi non posso offrire un modo diretto per farlo con i comandi incorporati, tuttavia è possibile sostituire una sezione di testo con l'output di essa eseguito attraverso un comando. Quindi, un semplice script come questo potrebbe essere utilizzato:

#!/usr/bin/python 

import sys 

input_lines = sys.stdin.readlines() 
sorted_lines = sorted(input_lines, 
         key=lambda line: map(int, line.split()[-1].split('.'))) 
for line in sorted_lines: 
    sys.stdout.write(line) 

Vedere https://www.linux.com/learn/tutorials/442419-vim-tips-working-with-external-commands, sezione "testo di filtraggio attraverso filtri esterni", che spiega come è possibile utilizzare questo come un filtro da vim.

Questo script dovrebbe fare ciò che si desidera e funzionerà su qualsiasi regione in cui tutte le linee selezionate terminano in un indirizzo IPv4.

+0

Bontà, grazie. Stavo cercando di evitare di passare attraverso uno script (principalmente perché si tratta di un server di produzione non ancora in produzione, quindi ha un'installazione bare-bare e 'python' non è lì), ma sembra incredibile; grazie! –

2

Esiste un modo affidabile per ottenere l'ordinamento corretto: anteporre gli zeri ai numeri di indirizzo in modo che siano tutti composti da tre cifre.

  1. Aggiungere gli zeri ai numeri.

    :%s/\<\d\d\?\>/0&/g|%&& 
    
  2. Ordinare le linee che confrontano gli indirizzi IP come testo.

    :sort r/\(\d\{3}\)\%(\.\d\{3}\)\{3}/ 
    
  3. striscia ridondanti zeri.

    :%s/\<00\?\ze\d//g 
    

Per eseguire tutti e tre i gradini come un comando, utilizzare l'uno-liner

:%s/\<\d\d\?\>/0&/g|%&&|sor r/\(\d\{3}\)\%(\.\d\{3}\)\{3}/|%s/\<00\?\ze\d//g 
Problemi correlati