情境:
要求
脚本:
awk -F'\t' -v OFS'\t' 'FNR==NR{a[substr($0,1,8)]=$4$3$2}
{if ($4$3$2 in a) printf ("77""\t"); else printf ("99""\t");print $0}' \
File2.txt File1.txt > File3.txt
文件1:
01 89 68 5000
02 89 11
03 89 00
06 89 00
07 89 19 RT 0428
01 87 23 5100
02 87 11
04 87 9 02
03 87 00
06 87 00
07 87 11 RT 0428
01 83 23 4900
02 83 11
04 83 9 02
03 83 00
06 83 00
07 83 11 RT 0428
文件2:
50006889 CCARD /3010 /E /C A87545457 / // ///11 ///
51002387 CCARD /3000 /E /S N054896334IV / // ///11 ///
51002390800666 CCARD /3000 /E /S N0978898IV / // ///11 ///
文件3: 当前输出
99 50006889 CCARD /3010 /E /C A87545457 / // ///11 ///
99
99 51002387 CCARD /3000 /E /S N054896334IV / // ///11 ///
99
99 51002390800666 CCARD /3000 /E /S N0978898IV / // ///11 ///
77 01 89 68 5000
99 02 89 11
99 03 89 00
99 06 89 00
99 07 89 19 RT
77 01 87 23 5100
99 02 87 11
99 04 87 9 02
99 03 87 00
99 06 87 00
99 07 87 11 RT 0428
99 01 83 23 4900
99 83 11
99 83 9 02
99 83 00
99 83 00
99 83 11 RT 0428
期望输出:
01 89 68 5000
02 89 11
03 89 00
06 89 00
07 89 19 RT 0428
77 50006889 CCARD /3010 /E /C A87545457 / // ///11 ///
01 87 23 5100
02 87 11
04 87 9 02
03 87 00
06 87 00
07 87 11 RT 0428
77 51002387 CCARD /3000 /E /S N054896334IV / // ///11 ///
99 51002390800666 CCARD /3000 /E /S N0978898IV / // ///11 ///
实际上对于77和99行,我需要整个字符串,但77和99仅在匹配键的开头。目前,如果字符串很长并且继续到第二行,则脚本也将77和99放在第二行的前面 我期待将77和99放在匹配的代码前面。
例如,以下是Jonathan修正后的awk代码的输出:
$ awk -f awk.script File2.txt File1.txt
01 89 68 5000
02 89 11
03 89 00
06 89 00
07 89 19 RT 0428
77 50006889 CCARD /3010 /E /C A87545457 / // ///11 ////3010 /E /C A87545457 / // ///11 ////3010 /E /C A87545457 / // ///11 ////3010 /E /C A87545457 / // ///11 ///
01 87 23 5100
02 87 11
04 87 9 02
03 87 00
06 87 00
07 87 11 RT 0428
77 51002387 CCARD /3000 /E /S N054896334IV / // ///11 ////3010 /E /C A87545457 / // ///11 ////3010 /E /C A87545457 / // ///11 ////3010 /E /C A87545457 / // ///11 ////3010 /E /C A87545457 / // ///11 ////3010 /E /C A87545457 / // ///11 ////3010 /E /C A87545457 / // ///11 ////3010 /E /C A87545457 / // ///11 ////3010 /E /C A87545457 / // ///11 ////3010 /E /C A87545457 / // ///11 ////3010 /E /C A87545457 / // ///11 ////3010 /E /C A87545457 / // ///11 ////3010 /E /C A87545457 / // ///11 ////3010 /E /C A87545457 / // ///11 ////3010 /E /C A87545457 / // ///11 ////3010 /E /C A87545457 / // ///11 ////3010 /E /C A87545457 / //
77 ///11 ////3010 /E /C A87545457 / // ///11 ////3010 /E /C A87545457 / // ///11 ////3010 /E /C A87545457 / // ///11 ///
01 83 23 4900
02 83 11
04 83 9 02
03 83 00
06 83 00
07 83 11 RT 0428
99 51002390800666 CCARD /3000 /E /S N0978898IV / // ///11 ////S N0978898IV / // ///11 ////S N0978898IV / // ///11 ////S N0978898IV / // ///11 ////S N0978898IV / // ///11 ////S N0978898IV / // ///11 ////S N0978898IV / // ///11 ////S N0978898IV / // ///11 ///////S N0978898IV / // ///11 ////S N0978898IV / // ///11 ////S N0978898IV / // ///11 ////S N0978898IV / // ///11 ///////S N0978898IV / // ///11 ////S N0978898IV / // ///11 ////S N0978898IV / // ///11 ////S N0978898IV / // ///11 ///////S N0978898IV
99 / // ///11 ////S N0978898IV / // ///11 ////S N0978898IV / // ///11 ////S N0978898IV / // ///11 ///////S N0978898IV / // ///11 ////S N0978898IV / // ///11 ////S N0978898IV / // ///11 ////S N0978898IV / // ///11 ///////S N0978898IV / // ///11 ////S N0978898IV / // ///11 ////S N0978898IV / // ///11 ////S N0978898IV / // ///11 ///////S N0978898IV / // ///11 ////S N0978898IV / // ///11 ////S N0978898IV / // ///11 ////S N0978898IV / // ///11 ///////S N0978898IV / // ///11 ////S N09
99 78898IV / // ///11 ////S N0978898IV / // ///11 ////S N0978898IV / // ///11 ///
$
答案 0 :(得分:1)
在阅读File2.txt
之前,您已正确阅读File1.txt
。但是,您需要忽略File2.txt
中的空白行。
FNR == NR && ! /^[[:space:]]*$/ { key = substr($1, 1, 8); a[key] = $0; next }
这使用第一个字段的前8个字符作为键,整行作为值。 next
确保不会以其他方式处理这些行。
下一部分是繁琐的。您需要在01
中找到$1
的行,然后从中构建一个键。当您下次获得01
行时,您需要打印出来自a
的77前缀行(并从a
删除该条目)。
最后,您需要从a
打印77前缀的行(并从a
删除条目)。然后,您需要处理a
中留下的任何条目,并为它们提供99前缀。
$1 == "01" { if (code != 0)
{
if (code in a)
{
printf("77\t%s\n", a[code])
delete a[code]
}
}
code = $4$3$2
}
{ print }
END {
if (code in a)
{
printf("77\t%s\n", a[code])
delete a[code]
}
for (code in a)
printf("99\t%s\n", a[code])
}
显然,你可以使用比我刚才更少的空白区域,尽管你可能还需要添加一些分号。出于测试目的,我将上面的代码放入文件awk.script
并运行:
$ awk -f awk.script File2.txt File1.txt
01 89 68 5000
02 89 11
03 89 00
06 89 00
07 89 19 RT 0428
77 50006889 CCARD /3010 /E /C A87545457 / // ///11 ///
01 87 23 5100
02 87 11
04 87 9 02
03 87 00
06 87 00
07 87 11 RT 0428
77 51002387 CCARD /3000 /E /S N054896334IV / // ///11 ///
01 83 23 4900
02 83 11
04 83 9 02
03 83 00
06 83 00
07 83 11 RT 0428
99 51002390800666 CCARD /3000 /E /S N0978898IV / // ///11 ///
$
这看起来与你想要的相似。如果要在上一个输出块之后留空行,请在打印77前缀行的printf("\n")
块之后添加if
。如果您喜欢I / O重定向,可以将其写入File3.txt
。您可以将脚本嵌入单引号中,并将其添加到命令行以代替-f awk.script
。如果你愿意的话,你可以将整个剧本压缩到一条巨大的线上 - 但请不要;这个程序的名称是awk
,而不是apl
。