我有两个文件,我要从一个文件中一个一个地搜索字符串,然后将记录更新到另一个文件中。说我有文本文件A.csv
TABLE1, ABC_STRING
TABLE2, ABC_STRING
TABLE3, ABC_STRING
B.csv
TABLEA,SOMEVALUE,ABC_STRING,NULL,ABC_STRING
TABLEB,SOMEVALUE,ABC_STRING,NULL,ABC_STRING
TABLE1,SOMEVALUE,ABC_INT,NULL,ABC_INT
TABLEC,SOMEVALUE,ABC_STRING,NULL,ABC_STRING
TABLE2,SOMEVALUE,ABC_INT,NULL,ABC_INT
TABLE3,SOMEVALUE,ABC_INT,NULL,ABC_INT
期望在新文件中输出,例如:
TABLEA,SOMEVALUE,ABC_STRING,NULL,ABC_STRING
TABLEB,SOMEVALUE,ABC_STRING,NULL,ABC_STRING
TABLE1,SOMEVALUE,ABC_STRING,NULL,ABC_STRING
TABLEC,SOMEVALUE,ABC_STRING,NULL,ABC_STRING
TABLE2,SOMEVALUE,ABC_STRING,NULL,ABC_STRING
TABLE3,SOMEVALUE,ABC_STRING,NULL,ABC_STRING
我尝试过这样:
for i in $(grep -w "ABC_STRING" A.csv | awk -F ',' '{print $1}'); do
grep -w "$i" B.csv | sed 's/ABC_INT/ABC_STRING/g'
done | more
我不确定如何编写命令来复制每一行,并检查是否包含该字符串(如果可用)。如果没有将其写入同一C.csv,请替换并写入C.csv。谁能提供符合我要求的代码段。
答案 0 :(得分:2)
awk -F', *' -v OFS=',' 'NR==FNR{m[$1]=$2; next} $1 in m{$3=$5=m[$1]} 1' A.csv B.csv > C.csv
答案 1 :(得分:1)
您可以尝试Perl
perl -pe '
BEGIN { %kv=map{chomp;split(",")} qx(cat A.csv) }
/^(.+?),/ and $kv{$1} and s/ABC_INT/ABC_STRING/g
'
使用给定的输入
$ perl -pe ' BEGIN {%kv=map{chomp;split(",")} qx(cat A.csv)} /^(.+?),/ and $kv{$1} and s/ABC_INT/ABC_STRING/g ' B.csv
TABLEA,SOMEVALUE,ABC_STRING,NULL,ABC_STRING
TABLEB,SOMEVALUE,ABC_STRING,NULL,ABC_STRING
TABLE1,SOMEVALUE,ABC_STRING,NULL,ABC_STRING
TABLEC,SOMEVALUE,ABC_STRING,NULL,ABC_STRING
TABLE2,SOMEVALUE,ABC_STRING,NULL,ABC_STRING
TABLE3,SOMEVALUE,ABC_STRING,NULL,ABC_STRING
$
答案 2 :(得分:0)
因为unix
cat <<EOF >A.csv
TABLE1, ABC_STRING
TABLE2, ABC_STRING
TABLE3, ABC_STRING
EOF
cat <<EOF >B.csv
TABLEA,SOMEVALUE,ABC_STRING,NULL,ABC_STRING
TABLEB,SOMEVALUE,ABC_STRING,NULL,ABC_STRING
TABLE1,SOMEVALUE,ABC_INT,NULL,ABC_INT
TABLEC,SOMEVALUE,ABC_STRING,NULL,ABC_STRING
TABLE2,SOMEVALUE,ABC_INT,NULL,ABC_INT
TABLE3,SOMEVALUE,ABC_INT,NULL,ABC_INT
EOF
# join the first file on the first field
# with the second file on the second field
# print unmatched lines from the second file
# the unknown matches are substituted with ##
# the output is complicated - we output the matched correct line (6 fields)
# and after it we output the original second file (6 fields)
# when there is no match, the last field from the correct line
# is the empty separator '##'
# we can filter is later with sed
join -11 -22 -t, -a2 -e'##' -o 2.1,2.2,2.3,1.2,2.5,1.2,2.1,2.2,2.3,2.4,2.5,2.6 <(
# dunno what the spaces are doing in A.csv, remove them
<A.csv tr -d ' ' |
# sort the file on the first field
sort -k1 -t,
) <(
# add a number of the lines to the second file
# so we can sort it like the original file later
<B.csv nl -s, -w1 |
# sort it on the second field (the first field is the number now)
sort -k2 -t,
) |
# here the output looks like:
# 6,TABLE3,SOMEVALUE,ABC_STRING,NULL,ABC_STRING,6,TABLE3,SOMEVALUE,ABC_INT,NULL,ABC_INT
# 1,TABLEA,SOMEVALUE,##,NULL,##,1,TABLEA,SOMEVALUE,ABC_STRING,NULL,ABC_STRING
# remove the first 6 fields from the lines with `##,` they were not matched
sed 's/.*,##,//' |
# extract first 6 fields, less to sort, operation is cheap
cut -d, -f1-6 |
# sort on the field numerical. This is the numbers we inserted in the second file
sort -k1 -t, -n |
# extract 5 lines from the original
cut -d, -f2-6