他のcsvルックアップテーブルの値を使用してcsvファイルに列を追加する

他のcsvルックアップテーブルの値を使用してcsvファイルに列を追加する

私はUnixに初めて触れたので、ここで私の問題に対する解決策を探しています。開始するコードがありません。 :) 問題と必要な解決策だけが必要です。

次のプロセスを自動化したいです(例:ExcelからVlookup機能をコピー)。

  • システムは、さまざまな数の列と区切り文字を使用して複数のCSVファイルを生成します。

生成されたすべてのファイルにはキー(トランザクション番号)が含まれています。このキーは、異なる文書間の異なる列に存在できます。

編集:抜粋は取引番号でソートされていないと仮定します。

たとえば、表1は次のとおりです。

field1,field2,field3,Transaction#,field4
ABC,ABC,ABC,1,CFG
ABC,ABC,ABC,2,CFG
ABC,ABC,ABC,3,CFG

たとえば、表2:

field1;Transaction#;field3;field4;field5
ABC;1;ABC;ABC;CFG
ABC;2;ABC;ABC;CFG
ABC;3;ABC;ABC;CFG
  • 次のルックアップテーブルがあります。

    Transaction#    New#
        1            122
        2            123
        3            124
    
  • 各csvテーブルの末尾にNew#というタイトルの列を追加する必要があります。

編集:ルックアップテーブル内のすべてのトランザクションが入力テーブルに存在せず、入力テーブル内のすべてのトランザクションがルックアップテーブルに存在しないと仮定します。

たとえば、表1は次のとおりです。

field1,field2,field3,Transaction#,field4,new#
ABC,ABC,ABC,1,CFG,122 
ABC,ABC,ABC,2,CFG,123
ABC,ABC,ABC,3,CFG,124

たとえば、表2:

field1;Transaction#;field3;field4;field5;new#
ABC;1;ABC;ABC;CFG;122
ABC;2;ABC;ABC;CFG;123
ABC;3;ABC;ABC;CFG;124

答え1

あなたのテーブルとルックアップファイルは両方ともCSVであり、同じ区切り文字を持ち、同じ参照規則を使用すると仮定します。そうでない場合は、まず他の手段で標準化する必要があります。

また、ルックアップファイルがメモリから読み取れるのに十分小さいと仮定します。そうでない場合は、データをSQLに変換する必要があります。

これらの仮定により、以下を使用できますawk

awk -F , -v OFS=, -v col=4 '
    NR == 1 { next }
    NR == FNR {
        n[$1] = $2
    }
    NR != FNR {
        NF++
        $NF = FNR == 1 ? "new" : n[$col]
        print
    }' lookup.csv Table1.csv

-FOFSおよびcol上記の項目を調整して、表のCSV区切り記号と関連列に一致させることができます。

答え2

私はテキスト処理ツールがタスクに依存しているとは思わない。代わりに、CSVファイルを処理するときに適切な言語を使用することをお勧めします。

以下はRの提案です(http://r-project.org、わからないと効果的にGoogleを検索するのは難しいです。)

#!/usr/bin/Rscript
args <- commandArgs(TRUE)

# Here, we read each table passed as argument on the commandline
tablenames <- list()
for (tablename in args) {
    header <- readLines(tablename, n=1)
    # we try to detect the separator (the character that surrounds "Transaction#")
    # That doesn't work if you use multi-characters separators
    sep <- sub(".*(.)Transaction#.*","\\1",header)
    if (nchar(sep[1]) != 1) {
        sep <- sub(".*Transaction#(.).*","\\1",header)
    }
    if (nchar(sep[1]) != 1) {
        print(paste0("Could not detect separator around column 'Transaction#' in file ",tablename))
    } else {
        # each table where the separator is succesfully detected
        # is added to a list of tablenames
        tablenames[[tablename]] <- list(name=tablename,sep=sep)
    }
}

# we parse each table in the list of tablenames
tables <- lapply(tablenames, function(tab) { read.csv(tab$name, check.names=FALSE, sep=tab$sep) })

# we also parse the lookup table, which has a different format
lookup <- read.table("lookup",header=TRUE,check.names=FALSE,comment.char="")

# then for each table, we add the new column
for (i in 1:length(tablenames)) {
  # This line magic:
  # - it adds a new column called "New#" to the table
  # - this column is populated from table lookup
  # - lines in lookup are filtered and ordered so that column "Transaction#" matches columns "Transaction#" in the table
  # - we add only column "New#" from lookup to the table
  tables[[i]][,"New#"] <- lookup[match(tables[[i]][,"Transaction#"],lookup[,"Transaction#"]),"New#"]

  # we write back the table under the name "new <original name>"
  write.table(tables[[i]], file=paste("new",tablenames[[i]]$name), sep=tablenames[[i]]$sep, quote=FALSE, row.names=FALSE)
}

テーブルがあるディレクトリからこのスクリプトを呼び出す必要があります。

./script table1 table2 ...

ここでtable1、、table2...はテーブルのファイル名です。スクリプトを作成するときは、ルックアップテーブルをファイルに含める必要がありますlookupが、これは簡単に変更できます。

たとえば、

1番テーブル

field1,field2,ffield1,field2,field3,Transaction#,field4
 ABC,ABC,ABC,1,CFG
 ABC,ABC,ABC,3,CFG

表2

field1;Transaction#;field3;field4;field5
ABC;2;ABC;ABC;CFG
ABC;1;ABC;ABC;CFG
ABC;3;ABC;ABC;CFG

私たちは走る./script.R table1 table2

探す

Transaction#   New#
    1            122
    2            123
    3            124

結果:

新しいテーブル1

field1,field2,field3,Transaction#,field4,New#
 ABC,ABC,ABC,1,CFG,122
 ABC,ABC,ABC,3,CFG,124

新しいテーブル2

field1;Transaction#;field3;field4;field5;New#
ABC;2;ABC;ABC;CFG;123
ABC;1;ABC;ABC;CFG;122
ABC;3;ABC;ABC;CFG;124

関連情報