我有一个相当大的CSV文件(75MB)。我只是想生成一个图形,所以我真的不需要所有数据。
重新措辞:我想删除n行,然后保留一行,然后删除n行,依此类推。
因此,如果文件如下所示:
Line 1
Line 2
Line 3
Line 4
Line 5
Line 6
并且n = 2,则输出为:
Line 3
Line 6
似乎sed
可以做到这一点,但我还没办法弄清楚。bash命令将是理想选择,但是我愿意接受任何解决方案。
我有一个相当大的CSV文件(75MB)。我只是想生成一个图形,所以我真的不需要所有数据。
重新措辞:我想删除n行,然后保留一行,然后删除n行,依此类推。
因此,如果文件如下所示:
Line 1
Line 2
Line 3
Line 4
Line 5
Line 6
并且n = 2,则输出为:
Line 3
Line 6
似乎sed
可以做到这一点,但我还没办法弄清楚。bash命令将是理想选择,但是我愿意接受任何解决方案。
Answers:
~ $ awk 'NR == 1 || NR % 3 == 0' yourfile
Line 1
Line 3
Line 6
NR
(记录数)变量是记录的行数,因为默认行为是RS
(记录分隔符)的新行。模式和动作是awk的默认格式,是可选的'pattern {actions}'
。当我们只提供模式部分时,然后为模式条件awk
写入所有字段。 $0
true
awk 'NR == 1 || NR % 3 == 0'
awk 'NR == 1 || NR % 2 == 0' myfile.txt | wc -l
,原始文件的行数为偶数,结果是奇数。@kev答案在我的测试案例中效果最好。
sed
也可以这样做:
$ sed -n '1p;0~3p' input.txt
Line 1
Line 3
Line 6
man sed
解释~
为:
first〜step匹配从第一行开始的每一步。例如,``sed -n 1〜2p''将打印输入流中的所有奇数行,并且地址2〜5将匹配从第五行开始的第二行。首先可以为零;在这种情况下,sed的运行就好像与step相同。(这是一个扩展。)
1p
打印第一行,0~3p
从第三行开始每三行打印一次(1p
因此需要打印第一行)。但是请注意,这0~3
不是标准的而是GNU sed扩展。
sed -n '1p;0~10p' '.\in.txt' > out.txt
将缩小的文件打印到输出文件中。
Perl也可以这样做:
while (<>) {
print if $. % 3 == 1;
}
该程序将打印其输入的第一行,然后每三行打印一次。
稍微解释一下的<>
是行输入运算符,它在这样的while
循环中使用时会在输入行上进行迭代。特殊变量$.
包含到目前为止读取的行数,并且%
是模数运算符。
使用-n
和-e
开关,可以将这些代码更紧凑地编写为单行代码:
perl -ne 'print if $. % 3 == 1' < input.txt > output.txt
该-e
开关需要一段Perl代码作为命令行参数执行,而该-n
开关则隐式地将代码包装在一个while
如上所示的循环中。
编辑:要实际获得第1、3、6、9,...行,如本例所示,而不是第1、4、7、10,...行,如我首先假设的那样,请替换$. % 3 == 1
为$. == 1 or $. % 3 == 0
。
如果要使用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";
将其另存为“ read_lines.sh”,并记住为bash文件提供+ x权限。
chmod +x ./read_lines.sh
./read_lines.sh > new_file.txt
。
Python版本(Python 2和Python 3):
python2 -c "print(''.join(open('file.txt').readlines()[::3]))"
替换[::3]
为开始,结束和步长参数以进行更多控制。例如[10:36:5]
,输出第10,15,...,35行。
注意,由于readlines()
保留了行尾,因此此调用的输出可能以空的最后一行结束,除非原始的最后一行被选定的步长放出。
流版本也是可能的(此处仅在完成流之后输出):
python -c "import sys;print(''.join(list(sys.stdin)[::3]))" < file.txt