I have a file that looks like this:
AE United Arab Emirates
AG Antigua & Barbuda
AN Netherlands Antilles
AS American Samoa
BA Bosnia and Herzegovina
BF Burkina Faso
BN Brunei Darussalam
And I 'd like to invert the order, printing first everything except $1 and then $1:
United Arab Emirates AE
How can I do the "everything except field 1" trick?
The following `awk` command uses the '-F' option and NR and NF to print the book names after skipping the first book. The '-F' option is used to separate the content of the file base on \t. NR is used to skip the first line, and NF is used to print the first column only.
awk to print the first column. The first column of any file can be printed by using $1 variable in awk. But if the value of the first column contains multiple words then only the first word of the first column prints. By using a specific delimiter, the first column can be printed properly.
txt. If you notice awk 'print $1' prints first word of each line. If you use $3, it will print 3rd word of each line.
awk '{ print $2; }' prints the second field of each line. This field happens to be the process ID from the ps aux output. xargs kill -${2:-'TERM'} takes the process IDs from the selected sidekiq processes and feeds them as arguments to a kill command.
$1=""
leaves a space as Ben Jackson mentioned, so use a for
loop:
awk '{for (i=2; i<=NF; i++) print $i}' filename
So if your string was "one two three", the output will be:
two
three
If you want the result in one row, you could do as follows:
awk '{for (i=2; i<NF; i++) printf $i " "; print $NF}' filename
This will give you: "two three"
Assigning $1
works but it will leave a leading space: awk '{first = $1; $1 = ""; print $0, first; }'
You can also find the number of columns in NF
and use that in a loop.
Use the cut
command with -f 2-
(POSIX) or --complement
(not POSIX):
$ echo a b c | cut -f 2- -d ' '
b c
$ echo a b c | cut -f 1 -d ' '
a
$ echo a b c | cut -f 1,2 -d ' '
a b
$ echo a b c | cut -f 1 -d ' ' --complement
b c
Maybe the most concise way:
$ awk '{$(NF+1)=$1;$1=""}sub(FS,"")' infile
United Arab Emirates AE
Antigua & Barbuda AG
Netherlands Antilles AN
American Samoa AS
Bosnia and Herzegovina BA
Burkina Faso BF
Brunei Darussalam BN
Explanation:
$(NF+1)=$1
: Generator of a "new" last field.
$1=""
: Set the original first field to null
sub(FS,"")
: After the first two actions {$(NF+1)=$1;$1=""}
get rid of the first field separator by using sub. The final print is implicit.
awk '{sub($1 FS,"")}7' YourFile
Remove the first field and separator, and print the result (7
is a non zero value so printing $0).
awk '{ saved = $1; $1 = ""; print substr($0, 2), saved }'
Setting the first field to ""
leaves a single copy of OFS
at the start of $0
. Assuming that OFS
is only a single character (by default, it's a single space), we can remove it with substr($0, 2)
. Then we append the saved copy of $1
.
If you're open to a Perl solution...
perl -lane 'print join " ",@F[1..$#F,0]' file
is a simple solution with an input/output separator of one space, which produces:
United Arab Emirates AE
Antigua & Barbuda AG
Netherlands Antilles AN
American Samoa AS
Bosnia and Herzegovina BA
Burkina Faso BF
Brunei Darussalam BN
This next one is slightly more complex
perl -F` ` -lane 'print join " ",@F[1..$#F,0]' file
and assumes that the input/output separator is two spaces:
United Arab Emirates AE
Antigua & Barbuda AG
Netherlands Antilles AN
American Samoa AS
Bosnia and Herzegovina BA
Burkina Faso BF
Brunei Darussalam BN
These command-line options are used:
-n
loop around every line of the input file, do not automatically print every line
-l
removes newlines before processing, and adds them back in afterwards
-a
autosplit mode – split input lines into the @F array. Defaults to splitting on whitespace
-F
autosplit modifier, in this example splits on ' ' (two spaces)
-e
execute the following perl code
@F
is the array of words in each line, indexed starting with 0$#F
is the number of words in @F
@F[1..$#F]
is an array slice of element 1 through the last element@F[1..$#F,0]
is an array slice of element 1 through the last element plus element 0
Let's move all the records to the next one and set the last one as the first:
$ awk '{a=$1; for (i=2; i<=NF; i++) $(i-1)=$i; $NF=a}1' file
United Arab Emirates AE
Antigua & Barbuda AG
Netherlands Antilles AN
American Samoa AS
Bosnia and Herzegovina BA
Burkina Faso BF
Brunei Darussalam BN
a=$1
save the first value into a temporary variable.for (i=2; i<=NF; i++) $(i-1)=$i
save the Nth field value into the (N-1)th field.$NF=a
save the first value ($1
) into the last field.{}1
true condition to make awk
perform the default action: {print $0}
.This way, if you happen to have another field separator, the result is also good:
$ cat c
AE-United-Arab-Emirates
AG-Antigua-&-Barbuda
AN-Netherlands-Antilles
AS-American-Samoa
BA-Bosnia-and-Herzegovina
BF-Burkina-Faso
BN-Brunei-Darussalam
$ awk 'BEGIN{OFS=FS="-"}{a=$1; for (i=2; i<=NF; i++) $(i-1)=$i; $NF=a}1' c
United-Arab-Emirates-AE
Antigua-&-Barbuda-AG
Netherlands-Antilles-AN
American-Samoa-AS
Bosnia-and-Herzegovina-BA
Burkina-Faso-BF
Brunei-Darussalam-BN
The field separator in gawk (at least) can be a string as well as a character (it can also be a regex). If your data is consistent, then this will work:
awk -F " " '{print $2,$1}' inputfile
That's two spaces between the double quotes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With