如何在csv文件上执行按行操作?

时间:2019-01-18 09:10:22

标签: linux bash grep

所以我有两个文件file.csvfile2.txt

file1.csv具有以下性质:

aaa,bbb,ccc,ddd
aab,bba,ccd,eee
fff,ggg,hhh,iii
jjj,kkk,lll,mmm

file2.txt具有以下性质:

aaa
jjj

所以我写了一段代码,查找file1.csv的第一列中是否存在file2.txt的内容,如果存在则删除整个行。

以下是命令:

grep -ivf file2.txt file1.csv>output.csv

所以在运行此命令后,我得到以下输出:

aab,bba,ccd,eee
fff,ggg,hhh,iii

我正在寻找的是对此的替代解决方案。我想打开file1.csv逐行读取第一列(最好将其加载到数组中),每次将其与file2.txt进行比较。我的实际脚本很大,我不想在两者之间创建任何临时文件,因此希望将file1第一列的内容加载到数组中,然后将其与file2.txt进行比较,最后将整个数组转储到一个csv文件。

2 个答案:

答案 0 :(得分:1)

注意:这是一个shell命令行,但是使用了其他工具。

由于CSV有点像数据库表,因此,如果您碰巧想执行可以表示为SQL的操作,那么使您像数据库表一样对待CSV并对其执行SQL查询的工具可能会很有用。查询。 fsql是一种这样的工具。假设您的CSV文件上有一个标题行:

file1.csv:

col1,col2,col3,col4
aaa,bbb,ccc,ddd
aab,bba,ccd,eee
fff,ggg,hhh,iii
jjj,kkk,lll,mmm

file2.txt:

col1
aaa
jjj

然后:

% fsql --add-csv file1.csv --add-csv file2.txt \
    "SELECT file1.* FROM file1 LEFT JOIN file2 ON file1.col1=file2.col WHERE file2.col1 IS NULL"

将导致:

col0,col1,col2,col3
aab,bba,ccd,eee
fff,ggg,hhh,iii

专业人士:您可以执行更复杂的操作,而不必处理复杂的cut或bash数组。骗局:不是最快的解决方案。

答案 1 :(得分:0)

Stricto sensu,关于您的要求:

  

我想打开file1.csv逐行读取第一列(最好将其加载到数组中),每次将其与file2.txt进行比较

您可以通过以下方式执行它:

#!/bin/bash

FILE1="/tmp/file1.csv"
FILE2="/tmp/file2.txt"

# Reads each row, one after the other.
while IFS= read -r row; do
  # Creates an array for the row.
  IFS=',' read -r -a rowAsArray <<< "$row"

  # Extracts the first column of the row.
  firstColumn="${rowAsArray[0]}"

  # Checks if this column exists in the filter file.
  # If it is NOT the case, prints the row which is kept.
  [ $( grep -ce "^$firstColumn$" "$FILE2" ) -eq 0 ] && echo "${rowAsArray[1]},${rowAsArray[3]}"

done < "$FILE1"

编辑:

  • 我添加了注释以解释脚本
  • 在此版本中,您拥有想要的数组
  • 最后,您可以调整要显示的列

    • 对于所有这些,只需使用“ $ {rowAsArray [@]}”
    • 对于特定的索引,例如在我的实例中,使用相应的索引,然后添加要添加的索引“ $ {rowAsArray [2]}” ...