我有一个相当大的 CSV 文件 (75MB)。我只是想制作它的图表,所以我真的不需要所有数据。
改写:我想删除 n 行,然后保留一行,然后删除 n 行,依此类推。
因此,如果文件如下所示:
Line 1
Line 2
Line 3
Line 4
Line 5
Line 6
Run Code Online (Sandbox Code Playgroud)
并且 n=2,那么输出将是:
Line 3
Line 6
Run Code Online (Sandbox Code Playgroud)
似乎sed可以做到这一点,但我一直无法弄清楚如何做到这一点。bash 命令是理想的,但我愿意接受任何解决方案。
Sel*_*lug 143
~ $ awk 'NR == 1 || NR % 3 == 0' yourfile
Line 1
Line 3
Line 6
Run Code Online (Sandbox Code Playgroud)
NR(记录数)变量是记录行数,因为默认行为是RS(记录分隔符)的新行。模式和动作在 awk 的默认格式中是可选的'pattern {actions}'。当我们只给出模式部分时,就会为我们的模式条件awk写入所有字段。 $0true
kev*_*kev 63
sed 也可以这样做:
$ sed -n '1p;0~3p' input.txt
Line 1
Line 3
Line 6
Run Code Online (Sandbox Code Playgroud)
man sed解释~为:
first~step 匹配从 line first 开始的每 step'th 行。例如,``sed -n 1~2p'' 将打印输入流中的所有奇数行,地址 2~5 将匹配每第五行,从第二行开始。第一个可以为零;在这种情况下,sed 的操作就好像它等于 step。(这是一个扩展。)
Ilm*_*nen 23
Perl也可以这样做:
while (<>) {
print if $. % 3 == 1;
}
Run Code Online (Sandbox Code Playgroud)
该程序将打印其输入的第一行,然后每隔三行打印一次。
稍微解释一下,<>是行输入运算符,当在这样的while循环中使用时,它会遍历输入行。特殊变量$.包含到目前为止读取的行数,并且%是模运算符。
使用-n和-e开关,可以将此代码更紧凑地编写为单行代码:
perl -ne 'print if $. % 3 == 1' < input.txt > output.txt
Run Code Online (Sandbox Code Playgroud)
所述-e交换机将一块Perl代码以执行作为命令行参数,而-n开关隐含在一个包装了代码while如上所示的一个环路。
编辑:要真正得到线1,3,6,9,...作为例子,而不是线1,4,7,10,......我先假设你想,替换$. % 3 == 1用$. == 1 or $. % 3 == 0。
小智 7
如果你想用Bash脚本来做,你可以尝试:
#!/bin/sh
echo Please enter the file name
read fname
echo Please enter the Nth lines that you want to keep
read n
exec<$fname
value=0
while read line
do
if [ $(( $value % $n )) -eq 0 ] ; then
echo -e "$line" >> new_file.txt
fi
let value=value+1
done
echo "Check the 'new_file.txt' that has been created in this directory";
Run Code Online (Sandbox Code Playgroud)
将其另存为“read_lines.sh”并记住为 bash 文件授予 +x 权限。
chmod +x ./read_lines.sh
Run Code Online (Sandbox Code Playgroud)
不产生进程的纯 bash 解决方案是:
{ for f in {1..2}; do read line; done;
while read line; do
echo $line;
for f in {1..2}; do read line; done;
done; } < file
Run Code Online (Sandbox Code Playgroud)
第一行跳过文件开头的 2 行,while打印下一行并再次跳过 2 行。
如果您的文件很小,这是一种非常有效的工作方式,因为它不会启动进程。当您的文件很大时,sed应该使用它,因为它在处理 io 方面比bash.
GNU coreutils split 可以做到这一点,例如:
seq 100 | split -n r/3/3
Run Code Online (Sandbox Code Playgroud)
解释:split -n r/i/n将取每行 k (从 0 开始计数),其中(k % n) + 1 = i.
如果这是一个 CSV 文件并且您需要保留标题,split -n r/1/3就可以了。