我有两个以列分隔的文件,我需要创建两个新文件,其中仅包含在两个文件中找到事务标识符的记录。标识符位于从第 9 列到第 14 列的字段中,但每个文件中的每条记录在 9-14 范围之前和之后都有唯一的数据,并且需要将可变数据转移到输出文件。每个标识符都保证出现一次或根本不出现。
我可以用 python 脚本来编写自己的脚本,但我没有看到太多对库中列分隔文件的本机支持,我觉得任何 *nix 系统(我在 Ubuntu 20.04 上)都应该有命令行实用程序专为以前的计算时代而构建,可以简单地处理这个问题。当然,如果该工具太陈旧,那么我会自己编写一个 python 脚本(除非您知道一个处理我没有看到的列分隔文件的包)。
感谢您的帮助。
示例:在每个文件中都找到包含第 9-14 列中的字符的一行ID:525
,因此这些行将写入各自的输出文件中。两个输入文件都有在另一个文件中找不到的记录。
输入文件1.txt
Record1 ID:525 DATA A
Record2 ID:232 DATA B
Record3 ID:811 DATA C
Record4 ID:400 DATA D
输入文件2.txt
Record1 ID:448 DATA E
Record2 ID:525 DATA F
输出文件1.txt
Record1 ID:525 DATA A
输出文件2.txt
Record2 ID:525 DATA F
答案1
GNU awk(又名)可在 Ubuntu 20.04 上使用,并且可以通过其变量gawk
处理固定宽度数据。FIELDWIDTHS
前任。最简单地说,给定
$ cat input_file1.txt
Record1 ID:525 DATA A
Record2 ID:232 DATA B
Record3 ID:811 DATA C
Record4 ID:400 DATA D
然后
$ gawk 'BEGIN{FIELDWIDTHS="8 6 *"} {print $2}' input_file1.txt
ID:525
ID:232
ID:811
ID:400
基于此,你可以做类似的事情
$ gawk '
BEGIN {FIELDWIDTHS = "8 6 *"}
BEGINFILE {outfile[ARGIND] = gensub("input","output","1",FILENAME)}
NR==FNR {a[$2] = $0; next}
($2 in a){
print a[$2] > outfile[1]
print $0 > outfile[2]
}
' input_file1.txt input_file2.txt
给予
$ head output_file?.txt
==> output_file1.txt <==
Record1 ID:525 DATA A
==> output_file2.txt <==
Record2 ID:525 DATA F
答案2
如果将每一行设置为字符串变量,则可以像这样检查第 9-14 列
myLine="Record1 ID:525 DATA A"
echo ${myLine:8:6}
${myLine:8:6}
从第 9 列开始(8+1,因为索引从 0 开始)并向前移动 6 个字符。
之后,您只需在每个文件中执行检查(可能使用 grep)
您甚至可以使用 awk 获取第二列(字符集,以空格分隔)并对其他文件执行检查。
在我的脑海中(没有测试过)你可以做如下的事情:
#!/bin/bash
// This is based on the example you gave, only using 2 input files
files=("input_file1.txt" "input_file2.txt")
out_baseName="output_file"
index=1
adder=1
for file in ${files[@]}; do
for line in $(cat $file); do
id_string=`echo $line | awk '{ print $2 }'` // gets the 2nd column "ID:525"
for subfile in ${files[@]}; do
if [ "$subfile" == "$file" ]; then
continue
fi
if grep "$id_string" $subfile; then
echo $line >> ${out_baseName}${index}.txt
grep "$id_string" $subfile >> ${out_baseName}$(($index+$adder)).txt
index=$(($index+1))
adder=$(($adder-1))
fi
done
done
done
答案3
第一种方法1:
作为检查的示例输入,我们可以通过考虑第 2 列来做到这一点
awk 'NR==FNR{a[$2];next}($2 in a){print $0}' inputfile1.txt inputfile2.txt >output_file2.txt
awk 'NR==FNR{a[$2];next}($2 in a){print $0}' inputfile2.txt inputfile1.txt >output_file1.txt
第二种方法:
awk 'NR==FNR{a[substr($0,9,6)];next}(substr($0,9,6) in a){print $0}' inputfile2.txt inputfile1.txt >output_file1.txt
awk 'NR==FNR{a[substr($0,9,6)];next}(substr($0,9,6) in a){print $0}' inputfile1.txt inputfile2.txt >output_file2.txt
输出
cat output_file1.txt
Record1 ID:525 DATA A
cat output_file2.txt
Record2 ID:525 DATA F