我想从一个有 90 行的文本文件中删除 10 条随机行,然后将其输出到一个新文件中。我一直在尝试使用 sed 来做到这一点,但我有两个问题。我正在使用:
sed -i $((1 + RANDOM & 90))d input.txt > output.txt
Run Code Online (Sandbox Code Playgroud)
然后运行命令 10 次(我认为有更好的方法来做到这一点!)
我遇到的第一个问题是我收到错误:
sed: -e 表达式 #1, char 2: 行地址 0 的无效使用
我认为这与它可能已经删除了第 1 行并再次尝试有关。
第二个问题是有时输出文件没有写入任何内容,即使它在使用相同命令之前工作。
您可能想使用RANDOM % 90
而不是&
. 这就是零的来源(删除第 1 行是可以的,在下一次运行中,这些行将被编号为 1 .. 89)。
但是有一个问题:公式可以多次生成相同的数字。为防止这种情况,请使用不同的方法:将数字随机排列并选择前十个:
shuf -i1-90 -n10 | sed 's/$/d/' | sed -f- input > output
Run Code Online (Sandbox Code Playgroud)
如果您不喜欢sed
生成sed
脚本,也可以使用printf
:
sed -f <( printf %dd\; $(shuf -i1-90 -n10) ) input > output
Run Code Online (Sandbox Code Playgroud)
如果您没有 GNU shuf
,可移植地,您可以这样做:
awk -v n=90 -v p=10 '
BEGIN {srand()}
rand() * n-- < p {p--; next}
{print}' < file
Run Code Online (Sandbox Code Playgroud)
它也将比具有高值的 shuf+sed 方法更有效,p
因为它在 o(n) 中,而 shuf+sed 在 o(n*p) 中。当 n=1000000 时,我的系统上的断点在 GNU sed 与 GNU awk 的 p=35 以及 GNU sed 与 mawk 的 p=1 左右(因为在 mawk 中总是更快)。