私はシェルスクリプトで機能を実装しようとしましたが、どういうわけか実装が中断され、助けが必要です。
Sample File - f1.txt
col1|col2|col3|rev|spt
A1|54|tyre|56.89|45.23
B1|54|pole|11.89|85.23
C1|54|ture|112.89|185.23
ファイルには複数の列があり、固定されていません。私が達成したいのは ->
Concatenate all the Columns in the File (Note- It can have any number of Columns) except the Columns- rev and spt
Whenever it Finds Column Name as rev or spot it shouldnot include in Concatenation.
Example-
Output-
KeyCol|rev|spot
A1~54~tyre|56.89|45.23
B1~54~pole|11.89|85.23
C1~54~ture|112.89|185.23
したがって、理想的には、必要な数の列(revとSpotという列を除く)を持つすべてのファイルにCompositeを作成したいと思います。
助けてください
答え1
awk
次のコマンドを使用できます。
awk -F'|' 'NR==1 {OFS=FS; print "KeyCol", $(NF-1), $NF} NR > 1 {OFS="~"; LAST=$(NF-1) FS $NF; NF-=2; print $0 FS LAST}'
説明する
-F '|'
入力フィールドの区切り記号があることを示します|
。NR==1
最初の行だけが機能していることを示します。最初の行では、最初のフィールドの「KeyCol」のみが印刷され、最後の2つのフィールドが印刷されOFS
(出力フィールド区切り記号)は(入力フィールド区切り文字)になります。FS
この場合です|
。- 最初の行の後の次の行()
NR > 1
:OFS="~"
新しい出力フィールド区切り記号があることを意味します~
。LAST=$(NF-1) FS $NF
- 最後の2つのフィールドを名前付き文字列変数に保存LAST
し、FS
(入力フィールドの区切り文字)で区切ります。NF-=2
-NF
最後の2つのフィールドを除外するには、フィールド数()を2だけ減らします。print $0 FS LAST
$0
最初の(NF-2)フィールドのみが保持されます。- これを印刷して使用します
OFS
(この場合~
- 以下は元のテキストです
FS
(例|
:)。 - LAST変数は最後の2つのフィールドを保持します。
出力
awk -F'|' 'NR==1 {OFS=FS; print "KeyCol", $(NF-1), $NF} NR > 1 {OFS="~"; LAST=$(NF-1) FS $NF; NF-=2; print $0 FS LAST}' f1.txt
KeyCol|rev|spt
A1~54~tyre|56.89|45.23
B1~54~pole|11.89|85.23
C1~54~ture|112.89|185.23
注1
OFS="~"
ラインをラインの端に移動できます。NR==1
これは、次のレコードにすべて適用され、すべての行に設定する必要がないためです。
awk -F'|' 'NR==1 {OFS=FS; print "KeyCol", $(NF-1), $NF; OFS="~"} NR > 1 {LAST=$(NF-1) FS $NF; NF-=2; print $0 FS LAST}'
ノート2
これを自動化するために awk スクリプトを作成できます。
$ cat composite.awk
BEGIN { FS = "|" }
NR == 1 {
OFS=FS
print "KeyCol", $(NF-1), $NF
OFS="~"
}
NR > 1 {
LAST=$(NF-1) FS $NF
NF-=2
print $0 FS LAST
}
commandに引数が必要ないようにBEGIN
設定セクションを追加しました。FS
-F '|'
awk
次に、スクリプトファイルを使用して実行します。
$ awk -f composite.awk f1.txt
KeyCol|rev|spt
A1~54~tyre|56.89|45.23
B1~54~pole|11.89|85.23
C1~54~ture|112.89|185.23