使用命令行实用程序执行以下地图更新
Using a command-line utility to perform the following map-updates
我是使用命令行实用程序的完全新手,想知道如何按以下方式处理信息:
mapping.txt
:
80 001 002
81 011 012 013 014
82 021 022
...
input.txt
:
81 103823044
80 103823054
81 103823064
...
想要output.txt
:
103823044|011|
103823044|012|
103823044|013|
103823044|014|
103823054|001|
103823054|002|
103823064|011|
103823064|012|
103823064|013|
103823064|014|
我已经完成了简单的映射,其中列号是固定的,但我不确定如何将动态数量的列映射到所需的输出
如果顺序不重要,join 和 awk 可以轻松完成。
$ join <(sort input.txt) <(sort mapping.txt) | awk -v OFS="|" '{for (i=3;i<NF;i++) print , $i OFS}'
103823054|001|
103823044|011|
103823044|012|
103823044|013|
103823064|011|
103823064|012|
103823064|013|
这是一个 GNU awk 脚本,它使用多维数组来执行您想要的操作:
#!/usr/bin/awk -f
BEGIN { OFS="|" }
FNR==NR { for(i=2;i<=NF;i++) a[][$i]; next }
in a { for(k in a[]) print , k, "" }
如果您将其保存到 script.awk
这样的文件中,然后 chmod +x script.awk
您可以 运行 像这样:
$ ./script.awk mapping.txt input.txt
103823044|011|
103823044|012|
103823044|013|
103823044|014|
103823054|002|
103823054|001|
103823064|011|
103823064|012|
103823064|013|
103823064|014|
这是脚本的细分:
BEGIN
- 将输出字段分隔符设置为 |
FNR==NR
- 处理第一个文件(mapping.txt
)并先按</code>,然后按其他字段将数据存储在多维数组中。 <code>next
跳过任何其他行处理。
in a
- 测试该行是否有映射。如果是这样,请按顺序打印出相应的映射(也是 GNU awk)。 print
命令中的逗号被转换为 OFS
值。
它可以重新制作成 "one-liner",例如:
awk -v OFS="|" 'FNR==NR {for(i=2;i<=NF;i++) a[][$i]; next} in a {for(k in a[]) print , k, ""}' mapping.txt input.txt
这是使用一维数组存储 [=25=]
然后 split()
稍后保存顺序的脚本版本:
#!/usr/bin/awk -f
BEGIN { OFS="|" }
FNR==NR { a[]=[=13=]; next }
in a { c=split(a[], b); for(i=2;i<=c;i++) print , b[i], "" }
我是使用命令行实用程序的完全新手,想知道如何按以下方式处理信息:
mapping.txt
:
80 001 002
81 011 012 013 014
82 021 022
...
input.txt
:
81 103823044
80 103823054
81 103823064
...
想要output.txt
:
103823044|011|
103823044|012|
103823044|013|
103823044|014|
103823054|001|
103823054|002|
103823064|011|
103823064|012|
103823064|013|
103823064|014|
我已经完成了简单的映射,其中列号是固定的,但我不确定如何将动态数量的列映射到所需的输出
如果顺序不重要,join 和 awk 可以轻松完成。
$ join <(sort input.txt) <(sort mapping.txt) | awk -v OFS="|" '{for (i=3;i<NF;i++) print , $i OFS}'
103823054|001|
103823044|011|
103823044|012|
103823044|013|
103823064|011|
103823064|012|
103823064|013|
这是一个 GNU awk 脚本,它使用多维数组来执行您想要的操作:
#!/usr/bin/awk -f
BEGIN { OFS="|" }
FNR==NR { for(i=2;i<=NF;i++) a[][$i]; next }
in a { for(k in a[]) print , k, "" }
如果您将其保存到 script.awk
这样的文件中,然后 chmod +x script.awk
您可以 运行 像这样:
$ ./script.awk mapping.txt input.txt
103823044|011|
103823044|012|
103823044|013|
103823044|014|
103823054|002|
103823054|001|
103823064|011|
103823064|012|
103823064|013|
103823064|014|
这是脚本的细分:
BEGIN
- 将输出字段分隔符设置为|
FNR==NR
- 处理第一个文件(mapping.txt
)并先按</code>,然后按其他字段将数据存储在多维数组中。 <code>next
跳过任何其他行处理。in a
- 测试该行是否有映射。如果是这样,请按顺序打印出相应的映射(也是 GNU awk)。print
命令中的逗号被转换为OFS
值。
它可以重新制作成 "one-liner",例如:
awk -v OFS="|" 'FNR==NR {for(i=2;i<=NF;i++) a[][$i]; next} in a {for(k in a[]) print , k, ""}' mapping.txt input.txt
这是使用一维数组存储 [=25=]
然后 split()
稍后保存顺序的脚本版本:
#!/usr/bin/awk -f
BEGIN { OFS="|" }
FNR==NR { a[]=[=13=]; next }
in a { c=split(a[], b); for(i=2;i<=c;i++) print , b[i], "" }