Pra*_*dam 7 command-line text-processing
我有一个包含 10000 行的文件,我想从中删除 5 个随机确定的行。我怎样才能做到这一点?
Byt*_*der 15
与需要每行处理整个文件一次才能删除的 for 循环相比,您可能可以更有效地解决它。
filename="/PATH/TO/FILE"
number=5
line_count="$(wc -l < "$filename")"
line_nums_to_delete="$(shuf -i "1-$line_count" -n "$number")"
sed_script="$(printf '%dd;' $line_nums_to_delete)"
sed -i.bak -e "$sed_script" "$filename"
Run Code Online (Sandbox Code Playgroud)
或者在一行中(在定义filename和number变量或手动替换它们之后):
sed -i.bak -e "$(printf '%dd;' $(shuf -i "1-$(wc -l < "$filename")" -n "$number"))" "$filename"
Run Code Online (Sandbox Code Playgroud)
该-i.bak开关告诉sed编辑/立即更换输入文件,但保留原始数据,命名为喜欢的输入文件的备份副本,但与.bak附加到文件名。如果您不想复制它,只需编写-i.
顺便说一句,您不必像我一样使用变量。您也可以直接用适当的值替换"$number"和"$filename"。为了清楚起见,我只是这样做了。
分解并解释命令的其余部分:
sed -e "SCRIPT" "$filename"
Run Code Online (Sandbox Code Playgroud)
sed在filename变量指定的文件上运行文本处理工具,应用作为SCRIPT参数给出的指令。
我们SCRIPT在它上面的行中动态生成,它们运行命令并将它们的输出分配给变量。这里我们使用这些命令:
wc -l < "$filename"读入由filename变量指定的文件并输出该文件包含的行数。
shuf -i "1-$line_count" -n "$number返回由number变量指定的数量在 1 到$line_count(包括两个边界)范围内的唯一随机数。
shuf -i 1-6 -n 2将模拟投掷两个常规六面骰子。printf '%dd;' ARGUMENTS返回一个格式化的字符串,包含所有ARGUMENTS(这次不引用以将每个随机数视为单独的参数)。格式字符串%dd;将在剩余参数时重复,并将%d替换为表示为十进制数的参数。
1 7 42将导致输出1d;7d;42d;。结果最终$sed_script是我们的SCRIPTfor sed。普通数字被视为地址,即应用操作的行号,输入文件的第一行从 1 开始。d是删除指定行的命令,;分隔多个sed脚本命令。
总之,整个命令首先检查filename变量中指定的输入文件并计算其行数。然后它生成number许多在 1 到行数范围内的唯一随机数,并从中构建一个sed脚本来删除每个提到的随机行。最后sed在文件上运行该脚本,修改它。
您可以使用 for 循环获取随机数并使用 sed 命令删除该行。
for i in {0..5};
do sed -i "$((1 + RANDOM % 10000))d" filename;
done
Run Code Online (Sandbox Code Playgroud)
小智 5
类似于 Shivaditya 的答案,但没有循环,并且会从整个文件中删除行而不仅仅是前 10 行:
sed -i "$((1+RANDOM%10000))d;$((1+RANDOM%10000))d;$((1+RANDOM%10000))d;$((1+RANDOM%10000))d;$((1+RANDOM%10000))d" filename
Run Code Online (Sandbox Code Playgroud)
将选择 1 到 10000 之间的五个随机数,并在一次操作中删除这些行。
| 归档时间: |
|
| 查看次数: |
2037 次 |
| 最近记录: |