Similar ao corte, você também pode fazer isso com o awk:
$ awk '{print $1,$2}' aa.txt && awk '{print $1,$3}' aa.txt
A red
B yellow
C blue
A green
B orange
C purple
# OR to send the output in a new file:
$ (awk '{print $1,$2}' aa.txt && awk '{print $1,$3}' aa.txt) >aaa.txt
A diferença é que o awk manipula melhor o espaço em branco do que o corte. Isso é útil se os campos de cada linha estiverem separados por mais de um espaço.
Por exemplo, se a linha do arquivo for A red
= um espaço separado, a solução de corte, conforme recomendado, também poderá ser executada com êxito, mas se a linha for A red
= 3 espaços, o corte falhará, enquanto o awk será bem-sucedido para obter os campos 1 e 2 ou os campos 1 e 3.
Atualização:
Como recomendado nos comentários (obrigado don_crissti) isto também pode ser feito em awk puro:
awk 'BEGIN{FS=OFS=" "}{z[NR]=$1FS$3; print $1,$2}END{for (i=1; i<=NR; i++){print z[i]}}' a.txt
Explicação:
FS : Input Field Separator
OFS : Output Field Separator
FS=OFS=" " : input & output field separator is set to "space"
z[NR] : Creating an array with name 'z' and index the record number:
z[1] for first line, z[2] for second line , z[3] for third line
z[NR]=$1FS$3 : to each array element assign field1-FieldSeparator FS=space)-field2
So for first line the fields1=A and Fields 3=green will be stored in z[1] => equals to z[1]="A green"
print $1,$2 : Justs prints on screen 1stfield (A) and 2ndfield (red) of the current line, printed separated by OFS
When the file is finished (END) then with a for loop we print out the whole z array entries => print z[i]
For i=1 => print z[1] => prints "A green"
For i=2 => print z[2] => prints "B orange"
For i=3 => print z[3] => prints "C purple"
PS: If fields are not separated by space but by tab , then Begin section of this awk one-liner must be changed to 'awk 'BEGIN {FS=OFS="\t"}....'