使用awk通过密钥文件从文件中获取值
Get Value from file by key file using awk
我是 awk 的新手,我正在尝试使用另一个文件中的键从文件中获取值。
值文件:
1 39485063845911 RANDOMTEXT RANDOMNUMBERS
1 39485063845912 RANDOMTEXT RANDOMNUMBERS
1 39485063845913 RANDOMTEXT RANDOMNUMBERS
1 39485063845914 RANDOMTEXT RANDOMNUMBERS
密钥文件:
1 39485063845911 RANDOMTEXT
1 39485063845912 RANDOMTEXT
我尝试改编我以前的 awk,但无法完成工作
awk 'BEGIN {FIELDWIDTHS="7 14 3 28 3 25"} NR==FNR {data["0"];next} NR!=FNR {FIELDWIDTHS="7 14 3 28"} {if(!() in data) {print [=12=]}}' file
FIELDWIDTHS里面的数字'represents'列的宽度(都是位置文件),</code>是关键列的宽度</p>
<p>所以上面例子的输出文件应该是:</p>
<pre><code>1 39485063845911 RANDOMTEXT RANDOMNUMBERS
1 39485063845912 RANDOMTEXT RANDOMNUMBERS
您的代码,为清晰起见,使用换行符:
awk '
BEGIN {FIELDWIDTHS="7 14 3 28 3 25"}
NR==FNR {data["0"];next}
NR!=FNR {FIELDWIDTHS="7 14 3 28"}
{if(!() in data) {print [=10=]}}
' file
- 您在第二个(或之后的)文件的每一行都设置了
FIELDWIDTHS
,而不是只设置一次 - 这是低效的
- 您只读取一个文件,因此不会打印任何内容
- 您似乎认为
</code> 在某种程度上与长度为 14</li> 的字段相关
<li>如果您想打印与密钥文件中的记录匹配的值文件中的记录,您似乎已经否定了您将使用的测试(您应该做 <code>if (x in y)
而不是 if (!(x in y))
)
也许您需要这样的东西:
gawk '
FNR==1 { FIELDWIDTHS = NR==FNR ? "7 14 3 28" : "7 14 3 28 3 25" }
NR==FNR { keys[]++; next }
in keys { print }
' keyfile valuefile
这个:
- 每个输入文件仅设置
FIELDWIDTHS
一次
- 同时使用密钥文件和值文件
- 指的是字段 2 (
</code>),它似乎是您希望成为密钥的字段</li>
<li>测试存在而不是不存在</li>
<li>明确使用 <code>gawk
而不是 awk
以避免令人讨厌的意外(如果使用不支持非 POSIX FIELDWIDTHS
的版本)
我知道您在问题中谈论的是 FIELDWIDTHS 和字符位置,但您也说过“我对 awk 有点陌生”并且您的脚本中有几个初学者错误,因此您可能不完全了解如何使用它并给出您提供的示例,您实际需要的是:
$ awk 'NR==FNR{a[]; next} in a' key values
1 39485063845911 RANDOMTEXT RANDOMNUMBERS
1 39485063845912 RANDOMTEXT RANDOMNUMBERS
如果这不是您所需要的全部,请编辑您的问题以提供更真实的示例input/output,包括上述方法不起作用的情况。
或者加入第三种可能性,这就像 grep -f
一样简单。例如:
grep -f keyfile valuefile
(注意: 这要求分隔两个文件之间的值的空格匹配。如果不匹配,则 awk
基于字段的方法是正确的)
使用密钥文件中的行在值文件中进行匹配。
例子Use/Output
对于上面的示例:
$ grep -f keyfile valuefile
1 39485063845911 RANDOMTEXT RANDOMNUMBERS
1 39485063845912 RANDOMTEXT RANDOMNUMBERS
我是 awk 的新手,我正在尝试使用另一个文件中的键从文件中获取值。
值文件:
1 39485063845911 RANDOMTEXT RANDOMNUMBERS
1 39485063845912 RANDOMTEXT RANDOMNUMBERS
1 39485063845913 RANDOMTEXT RANDOMNUMBERS
1 39485063845914 RANDOMTEXT RANDOMNUMBERS
密钥文件:
1 39485063845911 RANDOMTEXT
1 39485063845912 RANDOMTEXT
我尝试改编我以前的 awk,但无法完成工作
awk 'BEGIN {FIELDWIDTHS="7 14 3 28 3 25"} NR==FNR {data["0"];next} NR!=FNR {FIELDWIDTHS="7 14 3 28"} {if(!() in data) {print [=12=]}}' file
FIELDWIDTHS里面的数字'represents'列的宽度(都是位置文件),</code>是关键列的宽度</p>
<p>所以上面例子的输出文件应该是:</p>
<pre><code>1 39485063845911 RANDOMTEXT RANDOMNUMBERS
1 39485063845912 RANDOMTEXT RANDOMNUMBERS
您的代码,为清晰起见,使用换行符:
awk '
BEGIN {FIELDWIDTHS="7 14 3 28 3 25"}
NR==FNR {data["0"];next}
NR!=FNR {FIELDWIDTHS="7 14 3 28"}
{if(!() in data) {print [=10=]}}
' file
- 您在第二个(或之后的)文件的每一行都设置了
FIELDWIDTHS
,而不是只设置一次 - 这是低效的 - 您只读取一个文件,因此不会打印任何内容
- 您似乎认为
</code> 在某种程度上与长度为 14</li> 的字段相关 <li>如果您想打印与密钥文件中的记录匹配的值文件中的记录,您似乎已经否定了您将使用的测试(您应该做 <code>if (x in y)
而不是if (!(x in y))
)
也许您需要这样的东西:
gawk '
FNR==1 { FIELDWIDTHS = NR==FNR ? "7 14 3 28" : "7 14 3 28 3 25" }
NR==FNR { keys[]++; next }
in keys { print }
' keyfile valuefile
这个:
- 每个输入文件仅设置
FIELDWIDTHS
一次 - 同时使用密钥文件和值文件
- 指的是字段 2 (
</code>),它似乎是您希望成为密钥的字段</li> <li>测试存在而不是不存在</li> <li>明确使用 <code>gawk
而不是awk
以避免令人讨厌的意外(如果使用不支持非 POSIXFIELDWIDTHS
的版本)
我知道您在问题中谈论的是 FIELDWIDTHS 和字符位置,但您也说过“我对 awk 有点陌生”并且您的脚本中有几个初学者错误,因此您可能不完全了解如何使用它并给出您提供的示例,您实际需要的是:
$ awk 'NR==FNR{a[]; next} in a' key values
1 39485063845911 RANDOMTEXT RANDOMNUMBERS
1 39485063845912 RANDOMTEXT RANDOMNUMBERS
如果这不是您所需要的全部,请编辑您的问题以提供更真实的示例input/output,包括上述方法不起作用的情况。
或者加入第三种可能性,这就像 grep -f
一样简单。例如:
grep -f keyfile valuefile
(注意: 这要求分隔两个文件之间的值的空格匹配。如果不匹配,则 awk
基于字段的方法是正确的)
使用密钥文件中的行在值文件中进行匹配。
例子Use/Output
对于上面的示例:
$ grep -f keyfile valuefile
1 39485063845911 RANDOMTEXT RANDOMNUMBERS
1 39485063845912 RANDOMTEXT RANDOMNUMBERS