我有 2 个文本文件
AA;00000;
BB;11111;
GG;22222;
KK;WW;55555;11111;
KK;FF;ZZ;11111;
KK;RR;YY;11111;
我尝试生成此3.txt
输出:
AA;00000;
BB;11111;KK;WW;55555;KK;FF;ZZ;KK;RR;YY;
GG;22222;
在删除重复字段后,我应该有这个
AA;00000;
BB;11111;KK;WW;55555;FF;ZZ;RR;YY;
GG;22222;
简而言之:在由;
(FS=";")分隔的两个文件中,如果$n
文件 1 中的字段存在$m
于文件 2中的任何位置,其中 m,n 不为 1,则附加$0(file2,m)
到$0(file1,n)
. 必须避免重复字段。
我会尝试草拟一个解决方案
awk -f script.awk 2.txt 1.txt
其中脚本如下:
BEGIN {
FS=";"
OFS=";"
}
NR==FNR {
allRecordsFile2[i++] = $0;
next;
}
{
for(r in allRecordsFile2)
{
split(allRecordsFile2[r],";",array)
for(f in array)
{
for($2 through $n of file1 currently processed)
{
if $n == f --> $0 = $0";"allRecordsFile2[r]
}
}
}
## cleanup duplicates
print $0
}
我还需要敲定清理重复,但也许这可以通过拆分进行$0
通过";"
使用计数阵列跟踪重复的和。
但运行此脚本后,我返回语法错误
C:\Program Files (x86)\GnuWin32\bin>awk -f script.awk file2.txt file1.txt
awk: script.awk:17: for($2 through $n of filei currently processed)
awk: script.awk:17: “ syntax error
awk: script.awk:19: if $n == f --> $0 = $0";"allRecordsFile2[r]
awk: script.awk:19: “ syntax error
awk: script.awk:19: if $n == f --> $0 = $0";"allRecordsFile2[r]
awk: script.awk:19: “ syntax error
errcount:3
与其尝试基于FNR
/ 的顺序读取和控制NR
,为什么不使用getline
读取2.txt
和拆分';'
然后构建输出字符串(o
如下),将每一行的唯一组件连接起来?你可以做类似的事情:
awk '{
printf "%s", $0
}
/^BB/ {
o = ""
while (getline tmp < "2.txt") {
n = split (tmp,arr,";")
for (i=1; i<=n; i++)
if(!match($0,arr[i]) && !match(o,arr[i]))
o=o arr[i]";"
}
printf "%s", o
}
{
print ""
}
' 1.txt
示例使用/输出
使用1.txt
and 中的示例数据2.txt
(您1.txt
再次命名错误),您将收到:
$ awk '{
> printf "%s", $0
> }
> /^BB/ {
> o = ""
> while (getline tmp < "2.txt") {
> n = split (tmp,arr,";")
> for (i=1; i<=n; i++)
> if(!match($0,arr[i]) && !match(o,arr[i]))
> o=o arr[i]";"
> }
> printf "%s", o
> }
> {
> print ""
> }
> ' 1.txt
AA;00000;
BB;11111;KK;WW;55555;FF;ZZ;RR;YY;
GG;22222;
这看起来像你想要的。
作为以两个文件名作为参数的脚本
Windows 应遵循相同的约定,使用ARGV
. 请注意,在awk
脚本中运行时,不要在规则周围包含单引号,例如
#!/usr/bin/awk -f
NR != FNR {
exit
}
{
printf "%s", $0
}
/^BB/ {
o = ""
while (getline tmp < ARGV[2]) {
n = split (tmp,arr,";")
for (i=1; i<=n; i++)
if(!match($0,arr[i]) && !match(o,arr[i]))
o=o arr[i]";"
}
printf "%s", o
}
{
print ""
}
(注意:您需要将/usr/bin/awk
口译员更改为您拥有的任何内容)
用法是,例如 ./test.awk 1.txt 2.txt
如果这有帮助,请告诉我。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句