我有多个(1086)文件(.dat),在每个文件中我有5列和6384行。 我有一个名为“info.txt”的文件,其中包含2列和6883行。第一列给出行号(在.dat文件中删除),第二列给出一个数字。
1 600
2 100
3 210
4 1200
...等 我需要在info.txt中读取,找到第二列中对应于小于300的值的每一行号(所以在上面的示例中它是2和3)。然后我需要将这些值读入sed-awk或grep,并从每个.dat文件中删除这些#lines。 (所以我将在上面的例子中删除每个第2和第3行的dat文件。)
问题的更一般形式(我想): 如何将数字作为文件输入读取,而不是将它们分配给要从多个文件中删除的行。
我正在使用bash,但ksh帮助也很好。
答案 0 :(得分:0)
# create action list
cat info.txt | while read LineRef Index
do
if [ ${Index} -lt 300 ]
then
ActionReq="${ActionReq};${Index} b
"
fi
done
# apply action on files
for EachFile in ( YourListSelectionOf.dat )
do
sed -i -n -e "${ActionReq}
p" ${EachFile}
done
(未经测试,此处没有linux)。 sed对seconf值大于300的行的请求的限制。在此操作中,awk更有效。 我在第二个循环中使用sed来避免为每个要删除的行读取/写入每个文件。我认为第二个循环可以避免使用直接给sed代替文件的文件列表
答案 1 :(得分:0)
sed -i "$(awk '$2 < 300 { print $1 "d" }' info.txt)" *.dat
Awk脚本创建一个简单的sed
脚本来删除选定的行;它在所有*.dat
个文件上运行的脚本。
(如果你的sed
缺少-i
选项,则需要在循环中写入临时文件。在OSX和某些* BSD上,你需要-i ""
一个空参数。)
答案 2 :(得分:0)
这可能适合你(GNU sed):
sed -rn 's/^(\S+)\s*([1-9]|[1-9][0-9]|[12][0-9][0-9])$/\1d/p' info.txt |
sed -i -f - *.dat
这将构建要从info.txt
文件中删除的行的脚本,然后将其应用于.dat
文件。
N.B。根据OP请求,正则表达式适用于1到299之间的数字。
答案 3 :(得分:0)
这应该使用oldname_new.dat创建一个新的dat文件,但我还没有测试过:
awk 'FNR==NR{if($2<300)a[$1]=$1;next}
!(FNR in a)
{print >FILENAME"_new.dat"}' info.txt *.dat