使用 bash (sed/awk) 提取 CSV 文件中的行和列?
Posted
技术标签:
【中文标题】使用 bash (sed/awk) 提取 CSV 文件中的行和列?【英文标题】:using bash (sed/awk) to extract rows AND columns in CSV files? 【发布时间】:2013-01-07 16:36:57 【问题描述】:bash 是否能够处理从 csv 文件中提取行和列?希望我不必求助于 python..
我的 5 列 csv 文件如下所示:
Rank,Name,School,Major,Year
1,John,Harvard,Computer Science,3
2,Bill,Yale,Political Science,4
3,Mark,Stanford,Biology,1
4,Jane,Princeton,Electrical Engineering,3
5,Alex,MIT,Management Economics,2
我只想提取第 3、4、5 列的内容,忽略第一行,所以输出如下:
Harvard,Computer Science,3
Yale,Political Science,4
Stanford,Biology,1
Princeton,Electrical Engineering,3
MIT,Management Economics,2
到目前为止,我只能让 awk 打印出我的 CSV 文件的每一行或每一列,而不是像这种情况下的特定列/行! bash 可以这样做吗?
【问题讨论】:
奇怪的是,您很难让 awk 来执行此操作,因为打印字段(列)和行(记录)是 awk 设计用来做的最基本的事情。让我觉得这肯定比你到目前为止所描述的要多...... 【参考方案1】:试试这个
awk -F, 'NR > 1 OFS=",";print $3, $4, $5 ' temp.txt
或者这个
sed -re '1d;s/^[0-9],\w+,//g' temp.txt
【讨论】:
您能否解释一下您的修复程序在做什么? @JonEgerton,在 awk 中我添加了 OFS,在 sed 中我更加清晰,以便新用户可以看到我匹配的内容。在以前的答案中,正则表达式很短,但对于正则表达式的新用户来说很难理解。我的可能并不完美,但至少可以看到他们在做什么。他们工作【参考方案2】:grep '^,' outlook.contacts.csv | sed 's/^,\([^,]*\),[^,]*,\([^,]*\),.*/\1 \2/'
获取所有以,
开头的行,然后使用sed
将空白字段替换为名字和名字。
出于某种原因,一旦您将其粘贴到此行,请小心,因此您最好手动小心操作。
grep '^,' outlook.contacts.csv | sed 's/^,([^,]),[^,],([^,]),./\1 \2/'
【讨论】:
【参考方案3】:试试这个:
tail -n+2 file.csv | cut --delimiter=, -f3-5
【讨论】:
迄今为止最简单优雅的解决方案。【参考方案4】:我已经为这类任务创建了包 - gumba 如果您对 coffeescript 感到满意,可以尝试一下
cat file.csv | tail -n +2 | \
gumba "words(',').take((words)-> words.last(3)).join(',')"`
【讨论】:
【参考方案5】:这可能对你有用(GNU sed):
sed -r '1d;s/([^,]*,)2//' file
【讨论】:
【参考方案6】:perl -F, -lane 'if($.!=1)print join ",",@F[2,3,4];' your_file
查看here
【讨论】:
【参考方案7】:sed 1d file.csv | while IFS=, read first second rest; do echo "$rest"; done
【讨论】:
【参考方案8】:Bash 解决方案;
使用 IFS
#!/bin/bash
while IFS=',' read -r rank name school major year; do
echo -e "Rank\t: $rank\nName\t: $name\nSchool\t: $school\nMajor\t: $major\nYear\t: $year\n"
done < file.csv
IFS=$' \t\n'
使用字符串操作和数组
#!/bin/bash
declare -a arr
while read -r line; do
arr=($line//,/ )
printf "Rank\t: %s\nName\t: %s\nSchool\t: %s\nMajor\t: %s\nYear\t: %s\n" $arr[@]
done < file.csv
【讨论】:
相当笨拙,但我喜欢使用数组,我可能会在某些时候再次提及。更不用说这是一个仅限 bash 的解决方案。 这无法忽略引号中的逗号。示例 csv 行:"some, text",1,2
将被解析为:some
、text
、1
、2
而不是 some text
、1
、2
【参考方案9】:
给你,一个简单的 AWK 程序。
#!/usr/bin/awk -f
BEGIN
# set field separator to comma to split CSV fields
FS = ","
# NR > 1 skips the first line
NR > 1
# print only the desired fields
printf("%s,%s,%s\n", $3, $4, $5)
【讨论】:
如果设置OFS=","
,可以直接写print $3, $4, $5
【参考方案10】:
awk -F, 'NR > 1 print $3 "," $4 "," $5 '
NR 是当前行号,而 $3、$4 和 $5 是由 -F 给出的字符串分隔的字段
【讨论】:
您可以设置OFS=','
,这样您就不必在打印中连接逗号。【参考方案11】:
使用cut
和tail
:
tail -n +2 file.txt | cut -d ',' -f 3-
【讨论】:
OP 想跳过第一行,这就是我们使用tail
的原因。以上是关于使用 bash (sed/awk) 提取 CSV 文件中的行和列?的主要内容,如果未能解决你的问题,请参考以下文章
使用 bash、sed、awk 解析像 .ini 这样的文件
使用 sed / awk / bash 将缺失的行号填充到文件中
Linux bash 文本处理命令awk,sed,grep 用法
如何在bash脚本中使用Bash / Sed / Awk / Perl删除分隔字符串的最后一个元素[duplicate]