unix使用另一个文件的输入从多个文件中删除行

时间:2014-06-04 13:01:54

标签: bash unix awk sed grep

我有多个(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帮助也很好。

4 个答案:

答案 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