タブ区切りファイルの2つの列を1つにまとめる

タブ区切りファイルの2つの列を1つにまとめる

この形式のデータをタブ区切りファイルにインポートする方法を知りたいです。

A  red     green  
B  yellow  orange  
C  blue    purple  

そして、grep、貼り付け、切り取り、catなどのコマンドを使用して、次のように変換します。

A red
B yellow
C Blue
A green
B orange
C purple

答え1

Cutと同様に、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

違いは、awkが切り取りよりも空白を処理することです。この機能は、各行のフィールドが複数のスペースで区切られている場合に便利です。

たとえば、ファイル行A red= 1スペースで区切られている場合、提案された切り取りソリューションも成功しますが、行= A red3スペースである場合、切断は失敗し、awkはフィールド1と2、またはフィールド1と3を取得することに成功します。 。

更新:
コメントで提案されているように(don_crisstiのおかげで)、これは純粋なawkでも実行できます。

awk 'BEGIN{FS=OFS=" "}{z[NR]=$1FS$3; print $1,$2}END{for (i=1; i<=NR; i++){print z[i]}}' a.txt

説明する:

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"}....`

答え2

cutファイルに書き込むのが気に入らない場合(必要に応じて元のファイルを最初にコピー)、次のものを使用できます。

$ cut -f 1,3 file >> file && cut -f 1,2 file
A   red
B   yellow
C   blue
A   green  
B   orange  
C   purple 

説明する

  • cut -f 1,3 file最初と3番目の列を印刷しますfile(ほとんどのタブで区切られます)。
  • >> filefile端末に表示する代わりに出力を追加します。
  • &&動作したら、次のコマンドを実行します。
  • cut -f 1,2 filefile端末の最初と2番目の列のみを印刷します。

それfile自体は次のように表示されます。

A   red     green  
B   yellow  orange  
C   blue    purple  
A   green  
B   orange  
C   purple  

したがって、目的の最終出力をファイルとして取得するには、新しいファイルにリダイレクトする必要があります。

cut -f 1,3 file >> file && cut -f 1,2 file > file2

答え3

Zannaのソリューションと似ていますが、中間ファイル/結果はありません。

$ ( cut -f1,2 data && cut -f1,3 data ) >data.new

サブシェルの出力は最終ファイルに保存されますdata.new。サブシェルは最初に最初の2つの列を抽出し、次に最初と3番目の列を抽出します。

答え4

awk '{print 1 $1,$2; print 2 $1,$3}' ex |sort |cut -c 2-

更新:注文を維持するには、次の手順を実行します。

awk '{print 1,$1,$2; print 2,$1,$3}' ex |sort -sk1,1 |cut -c 3-
  • sort -sk1,1安定した最初のフィールドのソート

(\ありがとう{Kusalananda})

関連情報