2列の内容を置き換える

2列の内容を置き換える

クリッピングをよりよく理解し、クリッピングされたデータを別のファイルに移動しようとしています。 2つの列を持つ「Numbers」というファイルがあります。各列はタブで区切られます。

コマンドを使用してcut列を交換し、cutコマンド出力を別のファイルに保存しようとしています。問題なくフィールド2を切り取り、出力をcopynumberファイルに保存できます。しかし、cut出力ファイルのフィールド1フィールドをフィールド2に変換する方法がわかりません。

bashシェルスクリプトのみを使用してくださいawk

#I have tried the following commands:
$cat numbers
1       2
10      20
100     200
1000    2000
10000   20000
100000  300000
1000000 3000000

cat numbers | cut -f 2 > copynumbers

#How do I get field 1 from the original file into field 2 of the output file?
$cat copynumbers
2
20
200
2000
20000
300000
3000000

答え1

Perlに精通している場合は、次のユーティリティのコレクションの1つが役に立ちます。ここで、TSV入力はz5ファイルにあります。

$ recut 2,1 z5
2       1
20      10
200     100
2000    1000
20000   10000
300000  100000
3000000 1000000

再切断に関するいくつかの情報欠落しているTextutils集める:

recut   Process fields like cut, allow repetitions and re-ordering. (what)
Path    : ~/bin/recut
Version : - ( local: RepRev 1.1, ~/bin/recut, 2010-06-10 )
Length  : 56 lines
Type    : Perl script, ASCII text executable
Shebang : #!/usr/bin/perl
Home    : http://www1.cuni.cz/~obo/textutils/ (doc)
Modules : (for perl codes)
 Getopt::Long   2.42

私たちの店の共通tacは、以下の状況を処理します。

$ my-tac --field=0 z5
2 1
20 10
200 100
2000 1000
20000 10000
300000 100000
3000000 1000000

これまでにライブラリをリリースしていませんが、再作成したい場合は、次の方法に従ってください。

my-tac - reverse any one property: lines (like tac), fields, characters.

The default is to reverse the lines in a file, so a file like:
        a
        b
        c
will be printed as:
        c
        b
        a

usage: my-tac [options] -- [files]

options:

--help (or -h)
  print this message and quit.

--character
  Reverse order of characters in each line.  That is, given:
    abc
  the result is:
    cba

--field=0
  Reverse order of fields.  That is, given:
    Now is the time
  the result is:
    time the is Now

--field=i,j,k
  Reverse content of specific fields i,j,k.  That is given
    Now is the time
  my-tac --field=1,3  wil result in:
    woN is eht time

--para
  Reverse order of paragraphs, which are groups of lines
  separated by one of more empty lines.  If the last paragraph is
  not followed by an enpty line, one is supplied.

--number=n
  Print only n lines for a file reversal. <no limit>.

--debug
  Print internal debugging information.  <off>.
  (Must be first option.)

--separator=",re,string"
  Set the input separator to regular expression re, <\s+>, and
  the output separator to string, < >.  So the default is
  ",\s+, ".  Any character may be used in place of the comma, so
  you could specify:
    --separator=';\s+;|'

頑張って...乾杯、drl

答え2

使用プロセスの交換そしてpaste

$ paste <(cut -f2 numbers) <(cut -f1 numbers)
2        1
20       10
200      100
2000     1000
20000    10000
300000   100000
3000000  1000000

答え3

私の考えでは、awkこれを解決するために使用される方法は、通常「シェルスクリプト」と見なされるカテゴリに属します。

awk -F '\t' 'BEGIN { OFS=FS } { print $2, $1 }'

まず、ブロックを使用して入力区切り文字をtabに設定し、次にブロックは出力区切り-F '\t'文字BEGINを同じ文字に設定します。唯一のブロックの本文は、単に2つのフィールドを逆順に出力します。

テスト:

$ awk -F '\t' 'BEGIN { OFS=FS } { print $2, $1 }' numbers
2       1
20      10
200     100
2000    1000
20000   10000
300000  100000
3000000 1000000

すべての列を反転するより一般的な方法(数に関係なく):

BEGIN { OFS=FS }
{
    for (i = 1; i <= NF/2; ++i ) { 
        t=$i; $i=$(NF-i+1); $(NF-i+1)=t
    }
    print
}

これにより、行の最初から途中まで列を繰り返し、各列を最後の対応する列に置き換えます。奇数列を含む入力データの場合、中間列は変更されません。


列の1つを使用して一時ファイルを生成する初期アプローチを使用することも可能です。

cut -f 2 numbers >tmpfile

元のファイルをこのファイルに貼り付けると、3つの列(再び列2、1、2)を持つデータセットが作成されます。

paste tmpfile numbers

その後、次を使用して最後の列を削除できますcut

paste tmpfile numbers | cut -f 1,2

あるいは、一時ファイルなしで起動することもできます。

cut -f 2 numbers | paste - numbers | cut -f 1,2

使用されているすべてのソリューションは元のcutデータを2回読み取る必要があります(すべての列を元に戻す場合は通常、列数だけ読み取る)。

関連情報