9 command-line text-processing
我有一个 200 万行的文本文件。每行都有一个正整数。我正在尝试形成频率表之类的东西。
输入文件:
3
4
5
8
Run Code Online (Sandbox Code Playgroud)
输出应该是:
3
7
12
20
Run Code Online (Sandbox Code Playgroud)
我该怎么做?
mur*_*uru 20
与awk
:
awk '{total += $0; $0 = total}1'
Run Code Online (Sandbox Code Playgroud)
$0
是当前行。因此,对于每一行,我将其添加到total
,将该行设置为 new total
,然后尾随1
是一个 awk 快捷方式 - 它为每个真条件打印当前行,并且1
当条件评估为真时。
在 python 脚本中:
#!/usr/bin/env python3
import sys
f = sys.argv[1]; out = sys.argv[2]
n = 0
with open(out, "wt") as wr:
with open(f) as read:
for l in read:
n = n + int(l); wr.write(str(n)+"\n")
Run Code Online (Sandbox Code Playgroud)
add_last.py
使用源文件和目标输出文件作为参数运行它:
python3 /path/to/add_last.py <input_file> <output_file>
Run Code Online (Sandbox Code Playgroud)代码相当可读,但详细说明:
打开输出文件以写入结果
with open(out, "wt") as wr:
Run Code Online (Sandbox Code Playgroud)打开输入文件以每行读取
with open(f) as read:
for l in read:
Run Code Online (Sandbox Code Playgroud)读取行,将新行的值添加到总数中:
n = n + int(l)
Run Code Online (Sandbox Code Playgroud)将结果写入输出文件:
wr.write(str(n)+"\n")
Run Code Online (Sandbox Code Playgroud)只是为了好玩
$ sed 'a+p' file | dc -e0 -
3
7
12
20
Run Code Online (Sandbox Code Playgroud)
这是通过一个ppending+p
到输入的各行,然后传递结果给dc
计算器,其中
+ Pops two values off the stack, adds them, and pushes the result.
The precision of the result is determined only by the values of
the arguments, and is enough to be exact.
Run Code Online (Sandbox Code Playgroud)
然后
p Prints the value on the top of the stack, without altering the
stack. A newline is printed after the value.
Run Code Online (Sandbox Code Playgroud)
的-e0
参数推0
到dc
堆栈初始化的总和。
在 Bash 中:
#! /bin/bash
file="YOUR_FILE.txt"
TOTAL=0
while IFS= read -r line
do
TOTAL=$(( TOTAL + line ))
echo $TOTAL
done <"$file"
Run Code Online (Sandbox Code Playgroud)
要打印标准输入上给出的整数的部分和,每行一个:
#!/usr/bin/env python3
import sys
partial_sum = 0
for n in map(int, sys.stdin):
partial_sum += n
print(partial_sum)
Run Code Online (Sandbox Code Playgroud)
如果由于某种原因命令太慢;你可以使用 C 程序:
#include <stdint.h>
#include <ctype.h>
#include <stdio.h>
int main(void)
{
uintmax_t cumsum = 0, n = 0;
for (int c = EOF; (c = getchar()) != EOF; ) {
if (isdigit(c))
n = n * 10 + (c - '0');
else if (n) { // complete number
cumsum += n;
printf("%ju\n", cumsum);
n = 0;
}
}
if (n)
printf("%ju\n", cumsum + n);
return feof(stdin) ? 0 : 1;
}
Run Code Online (Sandbox Code Playgroud)
要构建并运行它,请键入:
$ cc cumsum.c -o cumsum
$ ./cumsum < input > output
Run Code Online (Sandbox Code Playgroud)
UINTMAX_MAX
是18446744073709551615
。
对于由以下生成的输入文件,C 代码比我机器上的 awk 命令快几倍:
$ cc cumsum.c -o cumsum
$ ./cumsum < input > output
Run Code Online (Sandbox Code Playgroud)
你可能想要这样的东西:
sort -n <filename> | uniq -c | awk 'BEGIN{print "Number\tFrequency"}{print $2"\t"$1}'
Run Code Online (Sandbox Code Playgroud)
命令的解释:
sort -n <filename> | uniq -c
对输入进行排序并返回一个频率表| awk 'BEGIN{print "Number\tFrequency"}{print $2"\t"$1}'
将 ooutput 变成更好的格式示例:
输入文件list.txt
:
4
5
3
4
4
2
3
4
5
Run Code Online (Sandbox Code Playgroud)
命令:
$ sort -n list.txt | uniq -c | awk 'BEGIN{print "Number\tFrequency"}{print $2"\t"$1}'
Number Frequency
2 1
3 2
4 4
5 2
Run Code Online (Sandbox Code Playgroud)
小智 5
你可以在 vim 中做到这一点。打开文件并键入以下按键:
qaqqayiwj@"<C-a>@aq@a:wq<cr>
Run Code Online (Sandbox Code Playgroud)
请注意,<C-a>
实际上是 ctrl-a,并且<cr>
是回车,即回车按钮。
这是它的工作原理。首先,我们要清除寄存器“a”,以便它在第一次通过时没有副作用。这简直了qaq
。然后我们执行以下操作:
qa " Start recording keystrokes into register 'a'
yiw " Yank this current number
j " Move down one line. This will break the loop on the last line
@" " Run the number we yanked as if it was typed, and then
<C-a> " increment the number under the cursor *n* times
@a " Call macro 'a'. While recording this will do nothing
q " Stop recording
@a " Call macro 'a', which will call itself creating a loop
Run Code Online (Sandbox Code Playgroud)
在这个递归宏运行完成后,我们只需调用:wq<cr>
保存并退出。
Perl 单行:
$ perl -lne 'print $sum+=$_' input.txt
3
7
12
20
Run Code Online (Sandbox Code Playgroud)
有 250 万行数字,处理大约需要 6.6 秒:
$ time perl -lne 'print $sum+=$_' large_input.txt > output.txt
0m06.64s real 0m05.42s user 0m00.09s system
$ wc -l large_input.txt
2500000 large_input.txt
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
8504 次 |
最近记录: |