Come stampare la terza colonna per l’ultima colonna?

Sto cercando di rimuovere le prime due colonne (di cui non sono interessato) da un file di registro DbgView. Non riesco a trovare un esempio che stampa dalla colonna 3 in poi fino alla fine della riga. Nota che ogni riga ha un numero variabile di colonne.

… o una soluzione più semplice: cut -f 3- INPUTFILE aggiungi il delimitatore (-d) corretto e cut -f 3- INPUTFILE lo stesso effetto.

 awk '{for(i=3;i<=NF;++i)print $i}' 

La risposta di Jonathan Feinberg stampa ogni campo su una riga separata. È ansible utilizzare printf per ribuild il record per l’output sulla stessa riga, ma è anche ansible spostare i campi un salto a sinistra.

 awk '{for (i=1; i<=NF-3; i++) $i = $(i+3); NF-=3; print}' logfile 
 awk '{$1=$2=$3=""}1' file 

NB: questo metodo lascerà “spazi vuoti” in 1,2,3 campi ma non è un problema se si vuole solo guardare all’output.

 awk -vm="\x0a" -v N="3" '{$N=m$N ;print substr($0, index($0,m)+1)}' 

Ciò riduce ciò che è prima del campo specificato n., N, e stampa tutto il resto della riga, incluso il campo n. N e mantenendo la spaziatura originale (non riformatta). Non importa se la stringa del campo appare anche da qualche altra parte nella linea, che è il problema con la risposta di Daisaa.

Definire una funzione:

 fromField () { awk -vm="\x0a" -v N="$1" '{$N=m$N; print substr($0,index($0,m)+1)}' } 

E usalo in questo modo:

 $ echo " bat bi iru lau bost " | fromField 3 iru lau bost $ echo " bat bi iru lau bost " | fromField 2 bi iru lau bost 

L’output mantiene tutto, inclusi gli spazi finali

Funziona bene per i file in cui ‘/ n’ è il separatore di record in modo da non avere quel carattere di nuova riga all’interno delle righe. Se si desidera utilizzarlo con altri separatori di record, utilizzare:

 awk -vm="\x01" -v N="3" '{$N=m$N ;print substr($0, index($0,m)+1)}' 

per esempio. Funziona bene con quasi tutti i file a patto che non utilizzino il char esadecimale. 1 all’interno delle linee.

Che dire della seguente linea:

  awk '{$ 1 = $ 2 = $ 3 = "";  stampa file 

Basato su suggerimento @ ghostdog74. Il mio dovrebbe comportarsi meglio quando filtri le linee, cioè:

  awk '/ ^ exim4-config / {$ 1 = "";  stampa file 

Se si desidera stampare le colonne dopo il terzo, ad esempio nella stessa riga, è ansible utilizzare:

 awk '{for(i=3; i<=NF; ++i) printf "%s ", $i; print ""}' 

Per esempio:

 Mar 09:39 20180301_123131.jpg Mar 13:28 20180301_124304.jpg Mar 13:35 20180301_124358.jpg Feb 09:45 Cisco_WebEx_Add-On.dmg Feb 12:49 Docker.dmg Feb 09:04 Grammarly.dmg Feb 09:20 Payslip 10459 %2828-02-2018%29.pdf 

Stamperà:

 20180301_123131.jpg 20180301_124304.jpg 20180301_124358.jpg Cisco_WebEx_Add-On.dmg Docker.dmg Grammarly.dmg Payslip 10459 %2828-02-2018%29.pdf 

Come possiamo vedere, la busta paga anche con lo spazio, mostra la linea corretta.

Bene, puoi facilmente ottenere lo stesso effetto usando un’espressione regolare. Supponendo che il separatore sia uno spazio, sembrerebbe:

 awk '{ sub(/[^ ]+ +[^ ]+ +/, ""); print }' 

Il seguente comando awk stampa gli ultimi N campi di ogni riga e alla fine della riga stampa un nuovo carattere di linea:

 awk '{for( i=6; i<=NF; i++ ){printf( "%s ", $i )}; printf( "\n"); }' 

Qui sotto trovi un esempio che elenca il contenuto della directory / usr / bin e quindi contiene le ultime 3 righe e poi stampa le ultime 4 colonne di ogni riga usando awk:

 $ ls -ltr /usr/bin/ | tail -3 -rwxr-xr-x 1 root root 14736 Jan 14 2014 bcomps -rwxr-xr-x 1 root root 10480 Jan 14 2014 acyclic -rwxr-xr-x 1 root root 35868448 May 22 2014 skype $ ls -ltr /usr/bin/ | tail -3 | awk '{for( i=6; i<=NF; i++ ){printf( "%s ", $i )}; printf( "\n"); }' Jan 14 2014 bcomps Jan 14 2014 acyclic May 22 2014 skype 

Soluzione Perl:

 perl -lane 'splice @F,0,2; print join " ",@F' file 

Queste opzioni della riga di comando sono utilizzate:

  • -n loop su ogni riga del file di input, non stampare automaticamente ogni riga

  • -l rimuove le newline prima dell’elaborazione e le aggiunge nuovamente in seguito

  • -a modalità autosplit – divide le linee di input nella matrice @F. Predefinito per la divisione su spazi vuoti

  • -e esegue il codice perl

splice @F,0,2 rimuove in modo pulito le colonne 0 e 1 dall’array @F

join " ",@F unisce gli elementi dell’array @F, usando uno spazio tra ogni elemento

Se il tuo file di input è delimitato da virgole, piuttosto che delimitato da spazi, usa -F, -lane


Soluzione Python:

python -c "import sys;[sys.stdout.write(' '.join(line.split()[2:]) + '\n') for line in sys.stdin]" < file

 awk '{a=match($0, $3); print substr($0,a)}' 

Innanzitutto trovi la posizione dell’inizio della terza colonna. Con substr si stampa l’intera riga ($ 0) iniziando dalla posizione (in questo caso a) fino alla fine della riga.

Un po ‘tardi qui, ma nessuno dei precedenti sembrava funzionare. Prova questo, usando printf, inserisce gli spazi tra ciascuno. Ho scelto di non avere newline alla fine.

 awk '{for(i=3;i<=NF;++i) printf("%s ", $i) }' 
 awk '{for (i=4; i<=NF; i++)printf("%c", $i); printf("\n");}' 

stampa i record a partire dal 4 ° campo fino all'ultimo campo nello stesso ordine in cui erano nel file originale

In Bash puoi utilizzare la seguente syntax con i parametri posizionali:

 while read -a cols; do echo ${cols[@]:2}; done < file.txt 

Ulteriori informazioni: Gestione dei parametri posizionali su Bash Hackers Wiki

Se si tratta solo di ignorare i primi due campi e se non si desidera uno spazio quando si mascherano quei campi (come alcune delle risposte sopra riportate):

 awk '{gsub($1" "$2" ",""); print;}' file 
 awk '{$1=$2=""}1' FILENAME | sed 's/\s\+//g' 

Le prime due colonne vengono cancellate, sed rimuove gli spazi iniziali.

Nelle colonne AWK sono chiamati campi, quindi NF è la chiave

tutte le righe:

 awk -F '' '{print $(NF-2)}'  

solo prima riga:

 awk -F '' 'NR<=1{print $(NF-2)}'