シェル変数を使用してあるフィールドを別のフィールドに置き換える方法は?

シェル変数を使用してあるフィールドを別のフィールドに置き換える方法は?

次のコードを考えてみましょう。

renamed_column='2
6
10
8
22
20
6-
18
8-
12
16'

array1='2 0.00000 -1.45191
6 0.81778 -0.63413
10 0.85020 -0.60170
8 1.40260 -0.04931
22 3.25781 1.80590
20 4.32051 2.86860
6 0.00000 -0.93906
18 0.07618 -0.86288
8 0.36922 -0.56984
12 0.71195 -0.22711
16 0.88517 -0.05389'

コマンドを使用して最初のフィールドを変更したいと思います$1array1renamed_columnawk

私の試みは使い方に基づいていましたが、うまくawk -v v="$renamed_column" '{$1=v; print $0}' <<< "$array1"いきません。

希望の出力は次のとおりです。

2 0.00000 -1.45191
6 0.81778 -0.63413
10 0.85020 -0.60170
8 1.40260 -0.04931
22 3.25781 1.80590
20 4.32051 2.86860
6- 0.00000 -0.93906
18 0.07618 -0.86288
8- 0.36922 -0.56984
12 0.71195 -0.22711
16 0.88517 -0.05389

答え1

$ awk -v v="$renamed_column" 'BEGIN{split(v,r)} {$1=r[NR]} 1' <<<"$array1"
2 0.00000 -1.45191
6 0.81778 -0.63413
10 0.85020 -0.60170
8 1.40260 -0.04931
22 3.25781 1.80590
20 4.32051 2.86860
6- 0.00000 -0.93906
18 0.07618 -0.86288
8- 0.36922 -0.56984
12 0.71195 -0.22711
16 0.88517 -0.05389

もちろん、これを行う他の方法もたくさんあります。上記は、元のコマンドを最小限に変更して実行する方法を示しています。

上記はシェルスカラー変数の内容をrenamed_columnawkスカラー変数に保存vし、内容をvawk配列に分割し、各最初のフィールドの値を変更して行ごとに入力し、現在の行によってインデックス付けされたr内容<<<"$array1"を追加します。します。r[]番号はに保存されますNR

答え2

array1.txt2つのファイルとその中にデータがある場合は、renamed_column.txt次のことができます。

awk -v replfile=renamed_column.txt '{getline x < replfile; $1 = x; print; }' array1.txt  > output.txt

たとえば、renamed_column.txt入力データの場合は、少し短くして入力してください。

20
6-
18
8-
12

そしてarray1.txtそれに対応する

20 4.32051 2.86860
6 0.00000 -0.93906
18 0.07618 -0.86288
8 0.36922 -0.56984
12 0.71195 -0.22711

それから結果output.txt

20 4.32051 2.86860
6- 0.00000 -0.93906
18 0.07618 -0.86288
8- 0.36922 -0.56984
12 0.71195 -0.22711

このようなシェル変数にデータがあり、そのように保持する必要がある場合は、Bash / ksh / zshでプロセスオーバーライドを使用してデータをawkにパイプすることができます。

awk -v replfile=<(echo "$renamed_column") '{getline x < replfile; $1 = x; print; }' <(echo "$array1")

しかし、awkを使用する計画であれば、ファイル内のデータを処理する方が簡単です。

答え3

~によるとこの回答へのコメント、データは質問のようにスペースで区切られず、タブで区切られます。これを念頭に置いて、以下のコードを修正しました。

paste代わりに、使用しているシェルがここで文字列リダイレクトをサポートしているとし、cut次を使用します。awk<<<"..."<(...)

paste - <( cut -f 2- <<<"$array1" ) <<<"$renamed_column"

pasteこれは、2つのタブで区切られたフィールドを生成し、ユーティリティの標準入力から読み取られた一時ファイルを作成するために使用されます。

標準入力(-コマンドラインでプレースホルダとして表示paste)は、文字列入力がリダイレクトされる最初のフィールドです$renamed_column

一時ファイルはプロセス置換によって動的に生成され、で処理される2番目のフィールドを提供しますpastecut文字列から最初のタブで区切られたフィールドを除くすべてのフィールドを抽出$array1し、他のhere文字列を介してその文字列を読み取るプロセスの置き換えが実行されます。

データがファイルにある場合は、上記の文字列リダイレクトをファイル名に変更してください。

paste new_column_1 <( cut -f 2- old_data )

関連情報