我有两个(巨大的~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脚本的初学者。)
谢谢!
答案 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