linux - 使用 SED 使用带有要删除的行号的索引来删除某些行
问题描述
我得到一个大文件,称为 file.txt,它可能有 20000 行或更多。其中一些行必须从原始文件中删除,并且必须创建一个包含剩余行的新文件,例如 newfile.txt。要删除的行在另一个文件中,例如 index.txt。所以我是这样的:
文件.txt:
line1
line2
...
line19999
line20000
索引.txt
11
56
79
...
19856
我一直在尝试使用 sed,试图让它使用索引中的数字来删除这些行,例如:
for i in ${index.txt[@]}
do
sed -i.back '${i}d' file.txt>newfile.txt
done
但是,我收到一条错误消息 ${index.txt[@]}: bad replacement ,我不知道如何解决这个问题。
我也尝试过使用 gawk,但是代码有问题,我认为这与文件缩进制表符有关。如果有人可以提供帮助,我将不胜感激。
解决方案
不要在循环中调用 sed,那会很慢。
您可以将索引文件转换为 sed 脚本,然后在数据文件上调用 sed 一次:
sed -i.bak "$(sed 's/$/d/' index.txt)" file.txt
或者,正如@Hazzard17 指出的那样,忽略不只包含数字的行:
script=$(sed -n '/^[[:blank:]]*[[:digit:]]\+[[:blank:]]*$/ s/$/d/p' index.txt)
sed -i.bak "$script" file.txt
一个演示:
$ seq 20000 | sed 's/^/line/' > file.txt
$ wc file.txt
20000 20000 188894 file.txt
$ seq 20000 | while read n; do [[ $RANDOM -le 5000 ]] && echo $n; done > index.txt
$ wc index.txt
3083 3083 16789 index.txt
$ sed -i.bak "$(sed 's/$/d/' index.txt)" file.txt
$ wc -l file.txt{,.bak}
16917 file.txt
20000 file.txt.bak
36917 total
要将文件读入数组,您可以执行以下操作:
mapfile -t indices < index.txt
for i in "${indices[@]}"; do ...; done
或者只是遍历文件
while IFS= read -r i; do ...; done < index.txt
推荐阅读
- mysql - 错误 1292 (22007) 的含义:截断不正确的 DOUBLE 值:'JAIN'
- asp.net-web-api-routing - 如果在不同的类中,相同路由的 GET 和 PUT 方法不起作用
- java - 如何在 web.xml 文件中指定文件路径
- python-3.x - 根据时间戳赋值
- android - 当我尝试更改按钮的状态时发生 NullPointerException
- cucumber - 在 aws 设备场的 cucber+testng 框架中的通用运行器类中获取空指针异常
- kotlin - 如何访问集合中每个对象的对象方法?
- javascript - 守法的 React Hooks
- scala - 为什么这段代码会抛出空指针异常
- c# - 如何解决 helix3d 模型中的缩放/定位问题?