opzione 1
C'è una soluzione che funziona con alcune versioni di awk:
awk '{ $(NF+1)=$1;$1="";$0=$0;} NF=NF ' infile.txt
Spiegazione:
$(NF+1)=$1 # add a new field equal to field 1.
$1="" # erase the contents of field 1.
$0=$0;} NF=NF # force a re-calc of fields.
# and use NF to promote a print.
Risultato:
United Arab Emirates AE
Antigua & Barbuda AG
Netherlands Antilles AN
American Samoa AS
Bosnia and Herzegovina BA
Burkina Faso BF
Brunei Darussalam BN
Tuttavia ciò potrebbe non riuscire con le versioni precedenti di awk.
opzione 2
awk '{ $(NF+1)=$1;$1="";sub(OFS,"");}1' infile.txt
Questo è:
awk '{ # call awk.
$(NF+1)=$1; # Add one trailing field.
$1=""; # Erase first field.
sub(OFS,""); # remove leading OFS.
}1' # print the line.
Nota che ciò che deve essere cancellato è l'OFS, non il FS. La linea viene ricalcolata quando viene assegnato il campo $ 1. Ciò cambia tutte le esecuzioni di FS in un OFS.
Ma anche questa opzione fallisce ancora con diversi delimitatori, come è chiaramente mostrato cambiando OFS:
awk -v OFS=';' '{ $(NF+1)=$1;$1="";sub(OFS,"");}1' infile.txt
Quella riga produrrà:
United;Arab;Emirates;AE
Antigua;&;Barbuda;AG
Netherlands;Antilles;AN
American;Samoa;AS
Bosnia;and;Herzegovina;BA
Burkina;Faso;BF
Brunei;Darussalam;BN
Ciò rivela che le serie di FS vengono cambiate in una OFS.
L'unico modo per evitarlo è evitare il ricalcolo del campo.
Una funzione che può evitare il ricalcolo è sub.
Il primo campo potrebbe essere catturato, quindi rimosso da $ 0 con sub, e poi entrambi ristampati.
Opzione 3
awk '{ a=$1;sub("[^"FS"]+["FS"]+",""); print $0, a;}' infile.txt
a=$1 # capture first field.
sub( " # replace:
[^"FS"]+ # A run of non-FS
["FS"]+ # followed by a run of FS.
" , "" # for nothing.
) # Default to $0 (the whole line.
print $0, a # Print in reverse order, with OFS.
United Arab Emirates AE
Antigua & Barbuda AG
Netherlands Antilles AN
American Samoa AS
Bosnia and Herzegovina BA
Burkina Faso BF
Brunei Darussalam BN
Anche se cambiamo FS, OFS e / o aggiungiamo più delimitatori, funziona.
Se il file di input viene modificato in:
AE..United....Arab....Emirates
AG..Antigua....&...Barbuda
AN..Netherlands...Antilles
AS..American...Samoa
BA..Bosnia...and...Herzegovina
BF..Burkina...Faso
BN..Brunei...Darussalam
E il comando cambia in:
awk -vFS='.' -vOFS=';' '{a=$1;sub("[^"FS"]+["FS"]+",""); print $0,a;}' infile.txt
L'output sarà (conservando ancora i delimitatori):
United....Arab....Emirates;AE
Antigua....&...Barbuda;AG
Netherlands...Antilles;AN
American...Samoa;AS
Bosnia...and...Herzegovina;BA
Burkina...Faso;BF
Brunei...Darussalam;BN
Il comando può essere espanso a diversi campi, ma solo con awk moderni e con l'opzione --re-interval attiva. Questo comando sul file originale:
awk -vn=2 '{a=$1;b=$2;sub("([^"FS"]+["FS"]+){"n"}","");print $0,a,b;}' infile.txt
Produrrà questo:
Arab Emirates AE United
& Barbuda AG Antigua
Antilles AN Netherlands
Samoa AS American
and Herzegovina BA Bosnia
Faso BF Burkina
Darussalam BN Brunei