【问题标题】:Problem replacing numbers with words from a file用文件中的单词替换数字的问题
【发布时间】:2019-09-04 15:49:21
【问题描述】:

我有两个文件:

在第一个 (champions.csv) 我有一些英雄联盟冠军的号码和名字

1,Annie
2,Olaf
3,Galio
4,Twisted Fate
5,Xin Zhao
6,Urgot
7,LeBlanc
8,Vladimir
9,Fiddlesticks
10,Kayle
11,Master Yi

在第二个(top.csv)中,我有几个冠军(第一列和第二列)以及他们赢得比赛的次数(第三列)

2,1,3
3,1,5
4,1,6
5,1,1
6,1,10
7,1,9
8,1,11
10,4,12
7,5,2
3,3,6

我需要用第一个文件的相应名称替换第二个文件的编号。

我尝试使用 awk 并将名称存储在一个数组中,但没有成功

lengthChampions=`cat champions.csv | wc -l`

for i in `seq 1 $length`; do
    name=`cat champions.csv | head -$i | tail -1 | awk -F',' '{print $2}'`

    champions[$i]=$name
done

for i in `seq 1 10`; do
    champion1=${champions[`cat top.csv | head -$i | tail -1 | awk -F',' '{print $1}'`]}
    champion2=${champions[`cat top.csv | head -$i | tail -1 | awk -F',' '{print $2}'`]}

    awk -F',' 'NR=='$i' {$1='$champion1'} {$2='$champion2'} {print $1","$2","$3}' top.csv > tmptop.csv && mv tmptop.csv top.csv
done

我想要一个解决这个问题的方法,可能代码比这个少。结果应该是这样的(不是我的文件的实际结果):

Ahri,Ashe,1502
Camille,Ezreal,892
Ekko,Dr. Mundo,777
Fizz,Caitlyn,650
Gnar,Ezreal,578
Fiora,Irelia,452
Janna,Graves,321
Jax,Jinx,245
Ashe,Corki,151
Katarina,Lee Sin,102

【问题讨论】:

  • 完全不清楚,Ashe 的输出来自哪里?请编辑与预期输出相关的示例,然后告诉我们。
  • 您输出中的1502 之类的数字是从哪里来的?为什么输入文件第二列的数字1在输出文件每一行的第二列变成不同的字符串?
  • 抱歉结果中的数字和名称错误。 Champion.csv 更大,第二个文件的数量也更大。结果只是一个例子。
  • @GuillermoMartínez,您无需发布完整文件,只需提供输入和预期输出示例,我们可以通过这些示例了解获取输出的逻辑。
  • @GuillermoMartínez @GuillermoMartínez minimal reproducible example 您提供的用于证明您的需求需要显示您希望从您显示的输入中产生的输出。显示来自其他一组输入的输出几乎没有那么有用!如果不清楚,请参阅How to Ask。哦,如果我是你,如果 top.csv 中的数字在 Champions.csv 中不存在,我会包含你想要输出的内容。

标签: shell awk sed


【解决方案1】:

这可以在一次 awk 调用中完成。将数字与数组中的冠军相关联,并将其用于替换第二个文件中的数字。

awk 'BEGIN{FS=OFS=","} NR==FNR{a[$1]=$2;next} {$1=a[$1];$2=a[$2]} 1' champions.csv top.csv 
Olaf,Annie,3
Galio,Annie,5
Twisted Fate,Annie,6
Xin Zhao,Annie,1
Urgot,Annie,10
LeBlanc,Annie,9
Vladimir,Annie,11
Kayle,Twisted Fate,12
LeBlanc,Xin Zhao,2
Galio,Galio,6

如果top.csv 中的某些数字在champions.csv 中不存在,请改用以下命令来防止这些数字被删除:

awk 'BEGIN{FS=OFS=","} NR==FNR{a[$1]=$2;next} ($1 in a){$1=a[$1]} ($2 in a){$2=a[$2]} 1' champions.csv top.csv

【讨论】:

  • 简单而强大。事实上,我猜它再简单不过了。
  • 我正在尝试这个命令,但我得到了这个:`shellscript ,3nnie ,5nnie ,6nnied Fate ,1nnieao ,10nie ,9nniec ,11nieir ,12isted Fate ,2in Zhao ,6alio
  • @GuillermoMartínez 当您的文件有 Windows 行结尾时会发生这种情况。使用此命令修复它dos2unix champions.csv top.csv
  • 或在NR==FNR...之前插入{sub(/\r/,"")}
  • 是的,这就是问题所在。谢谢你们的帮助
【解决方案2】:

假设 champions.csv第 2 列 不是太大,(ie 大于@987654321 的最大大小@数组${c[@]}),然后使用bashcut

readarray -t -O 1 c < <(cut -d, -f2 champions.csv)
while IFS=, read x y z; do 
    printf '%s,%s,%s\n' "${c[$x]}" "${c[$y]}" "$z" 
done < top.csv

输出:

Olaf,Annie,3
Galio,Annie,5
Twisted Fate,Annie,6
Xin Zhao,Annie,1
Urgot,Annie,10
LeBlanc,Annie,9
Vladimir,Annie,11
Kayle,Twisted Fate,12
LeBlanc,Xin Zhao,2
Galio,Galio,6

【讨论】:

    猜你喜欢
    • 2011-01-17
    • 2013-05-05
    • 1970-01-01
    • 2015-03-02
    • 1970-01-01
    • 1970-01-01
    • 2017-08-25
    • 2019-04-10
    相关资源
    最近更新 更多