我有一个文本文件A
,其中包含我想从文本文件中删除的行号B
。例如,文件A.txt
包含行
1
4
5
并且文件B.txt
包含行
A
B
C
D
E
生成的文件应该是:
B
C
当然,这可以手动完成
sed '1d;4d;5d' B.txt
但我想知道如何在不手动指定行号的情况下执行此操作。
答案1
您awk
也可以使用:
awk 'NR==FNR { nums[$0]; next } !(FNR in nums)' linenum infile
在特定情况下,当“linenum”文件可能为空时,awk 将跳过它,因此它不会打印整个“infile”行,要解决此问题,请使用以下命令:
awk 'NR==FNR && FILENAME==ARGV[1]{ nums[$0]; next } !(FNR in nums)' linenum infile
甚至更好(感谢斯蒂芬·查泽拉斯):
awk '!firstfile_proceed { nums[$0]; next }
!(FNR in nums)' linenum firstfile_proceed=1 infile
答案2
使用sed编写sed程序。
sed "$(sed 's/$/d/' A.txt)" B.txt > C.txt
“程序”可以变得更加复杂,例如它可以验证这些行是否只是数字,或者发明一种注释语法并将其删除。
答案3
另一种方法是结合基本的 shell 命令:
join -v1 <(nl file) line_numbers | cut -d' ' -f2-
或者:
nl file | join -v1 - line_numbers | cut -d' ' -f2-
用于nl
对文件的行进行编号,然后join -v1
仅保留第二个文件中不匹配的行,最后是cut
行号。文件line_numbers
必须排序。
答案4
for i in `cat fileA`; do sed -n ''$i'p' fileB; done >>content.txt
for i in `cat content.txt`; do sed -i '/^'$i'$/d' fileB;done
output
B
C