我可以使用grep来提取CSV文件的单个列吗?

时间:2017-12-04 16:52:06

标签: shell csv grep

我正在努力解决我必须尽快解决的问题。 我有一个csv文件,字段用;分隔。 我被要求使用grep制作一个shell命令,仅列出第三列,使用正则表达式。我不能用cut。这是一项练习。

我的档案是这样的:

1;Evan;Bell;39;Obigod Manor;Ekjipih;TN;25008
2;Wayne;Watkins;22;Lanme Place;Cotoiwi;NC;86578
3;Danny;Vega;25;Fofci Center;Momahbih;MS;21027
4;Larry;Robinson;23;Bammek Boulevard;Gaizatoh;NE;27517
5;Myrtie;Black;20;Savon Square;Gokubpat;PA;92219
6;Nellie;Greene;23;Utebu Plaza;Rotvezri;VA;17526
7;Clyde;Reynolds;19;Lupow Ridge;Kedkuha;WI;29749
8;Calvin;Reyes;47;Paad Loop;Beejdij;KS;29247
9;Douglas;Graves;43;Gouk Square;Sekolim;NY;13226
10;Josephine;Estrada;48;Ocgig Pike;Beheho;WI;87305
11;Eugene;Matthews;26;Daew Drive;Riftemij;ME;93302
12;Stanley;Tucker;54;Cure View;Woocabu;OH;45475
13;Lina;Holloway;41;Sajric River;Furutwe;ME;62184
14;Hettie;Carlson;57;Zuheho Pike;Gokrobo;PA;89098
15;Maud;Phelps;57;Lafni Drive;Gokemu;MD;87066
16;Della;Roberson;53;Zafe Glen;Celoshuv;WV;56749
17;Cory;Roberson;56;Riltav Manor;Uwsupep;LA;07983
18;Stella;Hayes;30;Omki Square;Figjitu;GA;35813
19;Robert;Griffin;22;Kiroc Road;Wiregu;OH;39594
20;Clyde;Reynolds;19;Lupow Ridge;Kedkuha;WI;29749
21;Calvin;Reyes;47;Paad Loop;Beejdij;KS;29247
22;Douglas;Graves;43;Gouk Square;Sekolim;NY;13226
23;Josephine;Estrada;48;Ocgig Pike;Beheho;WI;87305
24;Eugene;Matthews;26;Daew Drive;Riftemij;ME;93302

我想我应该使用类似:cat< test.csv | grep'regex'。

感谢。

3 个答案:

答案 0 :(得分:4)

正确的工作工具:使用awkcut

假设您要将第三列与特定字段匹配:

awk -F';' '$3 ~ /Foo/ { print $0 }' file.txt

...将打印第三个字段包含Foo的任何行。 (将print $0更改为print $3只会打印第三个字段。

如果您只想打印第三列,请使用cutcut -d';' -f3 <file.txt

错误的工作工具:使用GNU grep

grep具有-o选项的系统上,您可以将两个实例链接在一起 - 一个用于修剪第四列之后的所有内容(并删除少于四列的行),另一个用于只取最后一列(因此,第四列):

str='foo;bar;baz;qux;meh;whatever'
grep -Eo '^[^;]*[;][^;]*[;][^;]*[;][^;]*' <<<"$str" \
  | grep -Eo '[^;]+$'

解释其工作原理:

    方括号外的
  • ^仅匹配行的开头。
  • [^;]*匹配除;零次或多次之外的任何字符。
  • [;]仅匹配字符;

...因此,正则表达式中的每个[^;]*[;]都匹配单个字段,无论该字段是否包含文本。将其中四个放在第一阶段意味着我们只匹配字段,grep -o告诉grep仅发出它已成功匹配的内容。

答案 1 :(得分:2)

如果您只需要第3个字段,并且始终使用&#39;;&#39;为什么不使用&#39; cut&#39;?

cut -d';' -f3   <filename>  

更新:

OP不清楚,也许只想看第3行?

head -3 <filename> | tail -1 

或者......或许只是获取第3个字段中显示的内容列表?

不清楚&#39; grep&#39;的用途是什么?将会??

cut -d';' -f3   <filename>  | sort -u 

答案 2 :(得分:0)

正如其他答案所说,使用grep是一个糟糕/不幸的想法。

我能想到使用grep的唯一方法是拉出第3列==某个值的特定行。如,

grep '^\([^;]*;\)\{2\}Bell;' test.txt                                                           
1;Evan;Bell;39;Obigod Manor;Ekjipih;TN;25008

或者,如果第一列是索引(不将其计为列):

grep '^\([^;]*;\)\{3\}39;' test.txt  
1;Evan;Bell;39;Obigod Manor;Ekjipih;TN;25008

即使在这种情况下使用grep也会导致一个非常丑陋的解决方案。

编辑:没有看到查尔斯达菲的回答......那非常聪明。