如何根据第二个文件键对第一个文件 (csv) 进行排序

Sij*_*tha 5 linux awk sort csv

我试图找到一个解决方案,我可以根据第二个文件键使用第一列对我的第一个文件进行排序

第一个文件示例 (file1.csv)

COLUMN1 COlUMN2
apple fruit
dog animal
cat animal
cow animal
Run Code Online (Sandbox Code Playgroud)

第二个文件示例 (sort_keys.txt)

cat
dog
apple
cow
Run Code Online (Sandbox Code Playgroud)

预期输出(sorted.txt)

COLUMN1 COlUMN2
cat animal
dog animal
apple fruit
cow animal
Run Code Online (Sandbox Code Playgroud)

到目前为止,我发现 sort 命令和 awk 命令可能会有所帮助,但我没有任何工作代码。

$> awk 'NR==FNR{o[FNR]=$1; next} {t[$1]=$0} END{for(x=1; x<=FNR; x++){y=o[x]; print t[y]}}' sort_key.txt file1.csv

但是,此命令未按预期工作,并会就此寻求任何专家建议。PS 我确实有 Linux 命令知识,但这是非常具体的,我不知道如何实现这一点。

任何帮助或提示都非常感谢。

Ed *_*ton 8

$ awk 'NR==1; NR==FNR{a[$1]=$2; next} {print $1, a[$1]}' file1 sort_keys.txt
COLUMN1 COlUMN2
cat animal
dog animal
apple fruit
cow animal
Run Code Online (Sandbox Code Playgroud)


ste*_*ver 5

如果您有 GNU awk(又名gawk),您可以定义和使用您自己的自定义排序函数。

例如,假设 GNU awk > 4.0 的PROCINFO数组遍历特性:

$ gawk '
  function mysort(ia,va,ib,vb){return o[ia] - o[ib]}

  NR==FNR{o[$1]=FNR; next}      # map keys to numerical order

  FNR==1{print; next}           # print + skip the header line
  {a[$1]=$0}

  END{
    PROCINFO["sorted_in"] = "mysort"
    for(i in a) print a[i]
  }
' sort_key.txt file1.csv
COLUMN1 COlUMN2
cat animal
dog animal
apple fruit
cow animal
Run Code Online (Sandbox Code Playgroud)

(使用较旧的 GNU awks,您应该可以使用asorti.)


Ale*_*x O 3

如果您的数据不是很大,这是一个具有二次复杂度的简单解决方案:

cat sort_keys.txt | while read key ; do egrep "^$key " file1.csv ; done
Run Code Online (Sandbox Code Playgroud)

要添加/删除标头,请根据需要添加head和命令。tail

  • 不过,您确实需要精通 shell,才能理解“cat”没有做任何有用的事情(请参阅http://porkmail.org/era/unix/award.html),即使用管道到 while 循环是一种反模式(参见https://mywiki.wooledge.org/BashFAQ/001),循环的内容将在子shell中运行,读取是一次缓慢读取1个字节,而不是一次读取一行time,并将转换任何转义序列,例如 `foo\tbar` 将变为 `foo&lt;tab&gt;bar`,当 `key` 包含正则表达式元字符时,grep 将生成错误匹配,并且 `egrep` 已被弃用,以支持`grep -E`。 (3认同)