UNIX脚本 - 基于匹配第二个文件中字段的条件来更改一个文件的字段

时间:2015-08-12 09:02:32

标签: unix awk sed grep

我有两个(巨大的~100 GB)文件,其中多个字段的文本由行中的固定位置(未分隔)区分。

当File1中特定位置(例如,位置16-20)的文本包含的数值小于我选择的某个值(例如,小于-5)时,我希望更改相应的字段(也是在第二个文件中的线上固定位置给出一些预设值(比如10)。通过对应,我的意思是它们处于相同的行号(在下面的示例中 - 两者都在它们各自文件中的第3行)

E.g.File1:

  

ABC(11个空格)5.78 3.65 9.22(更重要的东西)

     

EFG(11个空格)4.78 9.65 9.99(更重要的东西)

     

HIJ(11个空格) -5.78 9.99 9.99(更重要的东西)

文件2(之前):

  

LMN(11个空格)31.21 2.14 1.27(更重要的东西)

     

OPQ(11个空格)4.78 9.99 9.99(更重要的东西)

     

RST(11个空格) 3.29 9.99 9.99(更重要的东西)

文件2(之后):

  

LMN(11个空格)31.21 2.14 1.27(更重要的东西)

     

OPQ(11个空格)4.78 9.99 9.99(更重要的东西)

     

RST(11个空格) 10.00 9.99 9.99(更重要的东西)

对于使用脚本实用程序的一些Unix专家来说,这似乎应该是一个非常简单的任务,但我对这些工具不熟悉,无法将它们串在一起并解决任务。我只能完成它的一部分,例如使用" cut"选择基于位置的字段。例如,我在以下bash脚本中完成了此操作:

#!/bin/bash
# PURPOSE: Process a file line by line with PIPED while-read loop.
FILENAME=$1
count=0
cat $FILENAME | while read LINE
do
xcoor=$(echo "$LINE" | cut -c 16-20)
let count++
if [ "$xcoor" -lt -4 ] 
then
echo "$count"
#I have identified the lines I want in the first file.  
#Now I need to modify the second file
fi
done

我的部分问题只是我一次处理2个文件。 最大的问题是前面提到的大量文件 - 这就是为什么我认为在逐行的基础上进行操作非常重要 - 避免将整个文件读入内存 - 或者不必要地编写临时文件。

非常感谢任何帮助,如果您非常友好地简要描述命令的组成部分,那将非常有用,因为我想了解这些命令的作用,以便我可以根据需要修改它们(我是Unix脚本的初学者。)

谢谢!

1 个答案:

答案 0 :(得分:2)

使用gawk

这样的话
gawk '
  BEGIN{FIELDWIDTHS="15 5 5"}      # widths of the fields - you will need to set this for your files
  FNR==NR{if($2<-5)r[NR]++;next}   # this processing only applies to file1
  FNR in r{$2="10.00"}             # this processing only applies to file2
  1' file1 file2                   # the '1' prints the record

LMN           31.21 2.14 1.27
OPQ            4.78 9.99 9.99
RST            10.00 9.99

因此,我们使用gawk的固定宽度字段读取这两个文件。阅读第一个时,请记下需要在数组r[]中修复的所有记录。阅读第二个时,修复需要它的任何记录,然后打印。

内存中唯一存在的是需要修复的所有记录号的列表。

我的输入文件可能与您的不同。如果需要,可以使用

将输出定向到新文件
gawk '...' file1 file2 > newFile