我想读取大型 csv 文件的第 n 行和第 m 行以及第 p 列和第 q 列之间的部分。有没有一种简单的方法可以用 shell 轻松完成此操作?(是否有我应该阅读文档的命令?否则,我将编写一个 python 脚本)
答案1
我有一个经过调整的脚本((N+1)q 部分是个好主意!)感谢@chronitis 的评论和所以回答:
#! /bin/bash
#
N=10
M=20
P=2
Q=3
sed -n "$N,${M}p; $((M+1))q" $1 | cut -d, -f$P-$Q
将文件另存为例如cut_csv
,使其可执行并使用
cut_csv file
它可以通过接受 N、M、P、Q 参数作为输入等变得更加奇特,但我很少使用它,所以我通常只是编辑文件。
怎么运行的:
主命令如下(假设 N=10、M=20、P=2、Q=3);shell 替换变量,最后一行将变为:(1)
sed -n "10,20p ; 21q" file | cut -d, -f2-3
让我们从第一个命令开始:
sed -n "10,20p ; 21q" file
man sed
这将在无打印模式( )下调用 sed(流编辑器, )-n
并对文件执行以下命令:
- 打印(
p
)10 到 20 之间的行(这是10,20p
部分) q
读取第 21 行时退出( )21q
,以便丢弃文件的其余部分
sed 的输出通过管道( |
)传输到cut
:
cut -d, -f2-3
此命令 ( man cut
) 选择一行的字段(并对每一行重复此操作)。在本例中,我告诉它字段(列)之间的分隔符是逗号 ( -d,
),并打印出 2 到 3 之间的列。
作为另一个更复杂的例子,我经常使用这个:
sed -n "1p; 10,14p; 21q" data.csv | cut -d, -f1,4-8
这将选择第 1 行(其中有标题 :-))和第 10 到第 14 行(5 行);然后选择第 1 列(我的数据中的时间...)和第 4 到第 8 列。一旦掌握它,它就真的很强大。
(1)查看 shell 正在做什么的一个好方法是将第一行(称为舍邦) 像那样:
#! /bin/bash -xv
shell 现在将打印它读取的每个命令以及替换的结果:
(0)asus-rmano: part_of_csv.sh p20dedo.csv
#! /bin/bash -xv
#
N=10
+ N=10
M=20
+ M=20
P=2
+ P=2
Q=3
+ Q=3
sed -n "$N,${M}p; $((M+1))q" $1 | cut -d, -f$P-$Q
+ cut -d, -f2-3
+ sed -n '10,20p; 21q' p20dedo.csv
16:05:49,000
16:05:51,000
[...]
答案2
您可以使用管道将 awk 和 sed 结合起来
sed -n '10,50p' file.csv | awk -F ';' '{print $3 $4}'
10 和 50 是行。
-F';'是字段分隔符。(在我的示例中是分号)
$3 和 $4 是需要显示的字段。
答案3
以下脚本使用head
并tail
能够打印.csv
通过行号和列号过滤的文件的一部分。
#!/bin/bash
m="$2"
n="$3"
s="$4"
t="$5"
head -n "$n" "$1" | tail -n +"$m" | cut -d, -f "$s"-"$t"
将上述脚本保存为csv_view.sh
并使其可执行。
chmod +x csv_view.sh
在哪里,
m=row number where to begin
n=row number where to end
n=column number where to begin
n=column number where to end
如何使用
./csv_view.sh mycsvfile.csv 11 32 4 7
它将打印第 11 至 32 行和第 4 至 7 列mycsvfile.csv