[英]Printing numerous specific lines from file using awk or sed command loop
我有一个带有ID名称的大型txt文件。 它有2500行,一列。 我们称它为file.txt
H3430
H3467
H9805
另外,我还有另一个文件index.txt,其中包含390个数字:
1
4
9
13
15
这些数字是我必须从file.txt中提取的(ID的)行数。 我需要生成另一个文件,称为newfile.txt,它只有index.txt要求的特定行中的390个ID(列表的第一个ID,第四个,第九个,依此类推)。
因此,我尝试执行以下循环,但没有成功。
num=$'index.txt'
for i in num
do
awk 'NR==i' "file.txt" > newfile.txt
done
对于这个问题,我是个菜鸟。所以,我需要一些帮助。 即使是在我的循环或您建议的新解决方案中。 谢谢 :)
让我们创建一个示例文件,使用seq
模拟您的2500行文件:
$ seq 2500 > /tmp/2500
并使用示例将行号打印到名为390的文件中:
$ echo "1
4
9
13
15" > /tmp/390
您可以通过将行号读取到数组中并在该数组中打印行来在文件2500中打印N行:
$ awk 'NR==FNR{ a[$1]++; next} a[FNR]' /tmp/390 /tmp/2500
您还可以使用sed
命令文件:
$ sed 's/$/p/' /tmp/390 > /tmp/sed_cmd
$ sed -n -f /tmp/sed_cmd /tmp/2500
使用GNU sed,您可以sed 's/$/p/' /tmp/390 | sed -n -f - /tmp/2500
sed 's/$/p/' /tmp/390 | sed -n -f - /tmp/2500
但在OS X上不起作用:-(
您可以这样做:
$ sed -n -f <(sed 's/$/p/' /tmp/390) /tmp/2500
您可以将index.txt文件读入地图,然后将其与file.txt的行号进行比较。 将输出重定向到另一个文件。
awk 'NR==FNR{line[$1]; next}(FNR in line){print $1}' index.txt file.txt > newfile.txt
当您使用两个文件时,必须使用FNR,因为新文件启动时它将重置为1(相反,NR将继续增加)。
正如Ed Morton在评论中建议的那样。 然后可以对命令进行优化,以进一步删除{print $1}
因为awk默认情况下会根据真相进行打印。
awk 'NR==FNR{line[$1]; next} FNR in line' index.txt file.txt > newfile.txt
如果index.txt
已排序,我们可以按顺序遍历file.txt
。
这样可以将操作数量减少到最少(更快的脚本):
awk 'BEGIN
{ indexfile="index.txt"
if ( (getline ind < indexfile) <= 0)
{ printf("Empty %s\n; exiting",indexfile);exit }
}
{ if ( FNR < ind ) next
if ( FNR == ind ) printf("%s %s\n",ind,$0)
if ( (getline ind < indexfile) <= 0) {exit}
}' file.txt
如果文件未真正排序,请使用sort快速排序:
sort -n index.txt > temp.index.txt
rm index.txt
mv temp.index.txt index.txt
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.