使用awk使用不同的字段分隔符处理2个文件

使用awk使用不同的字段分隔符处理2个文件,awk,Awk,假设我有两个文件: $ cat file1 A:10 B:5 C:12 $ cat file2 100 A 50 B 42 C 我想要一些像: A 10 100 B 5 50 C 12 42 我试过这个: awk 'BEGIN{FS=":"}NR==FNR{a[$1]=$2;next}{FS=" ";print $2,a[$2],$1}' file1 file2 这让我明白: 100 A B 5 50 C 12 42 我猜问题来自字段分隔符,它对于第二个文件设置得太晚了。如何为不同

假设我有两个文件:

$ cat file1
A:10
B:5
C:12

$ cat file2
100 A
50 B
42 C
我想要一些像:

A 10 100
B 5 50
C 12 42
我试过这个:

awk 'BEGIN{FS=":"}NR==FNR{a[$1]=$2;next}{FS=" ";print $2,a[$2],$1}' file1 file2
这让我明白:

  100 A
B 5 50
C 12 42
我猜问题来自字段分隔符,它对于第二个文件设置得太晚了。如何为不同的文件(而不是单个文件)设置不同的字段分隔符

谢谢


编辑:更一般的情况

对于像这样的文件2和文件3:

$ cat file3
A:10 foo
B:5 bar 
C:12 baz
如何获得:

A 10 foo 100
B 5 bar 50
C 12 baz 42

更改FS后,您需要让awk重新拆分
$0

您可以使用
$0=$0
来实现这一点(例如)

所以最后一个块中的
{FS=”“;$0=$0;…}
将执行您想要的操作


尽管仅在第一次需要更改FS时这样做可能会对大文件的性能稍好一些。

您可以尝试以下方法:

$ cat f1
A:10
B:5
C:12
或设置多个字段分隔符

$ awk -F"[: ]" 'NR==FNR{a[$1]=$2;next}$2 in a{print $2,a[$2],$1}' f1 f2
A 10 100
B 5 50
C 12 42

只需在文件之间设置FS:

awk '...' FS=":" file1 FS=" " file2
i、 e:


@jeanrjc在这里成功了。您使用的是哪个版本的
awk
?当你这样做的时候,输出有变化吗?没有变化。我使用的是BSD版本的awk(Mac用户)@jeanrjc,你运行了
awk'BEGIN{FS=“:”}NR==FNR{a[$1]=$2;next}{FS=“;$0=$0;print$2,a[$2],$1}'file1 file2
,仍然得到了你的原始输出?是的!(我复制粘贴了你写的东西,输出结果仍然相同)这很奇怪。您可以尝试保存
$1
,将其设置为其他值,然后将其设置回保存的值。这可能会迫使重新拆分,
$0=$0
不会,但我不知道。你也可以试试
$1=$1
而不是
$0=$0
,看看这是否有效。中的
2与他的原始脚本不同。当
file2
包含
file1
@EtanReisner中未出现的行时,它将省略原始文件可能会产生的输出。这是正确的,但在执行此类实现时,这通常是正确的方法。OP没有说明他是否想保留这些行,但我很感谢你的反馈,因为这可以帮助OP做出决定,让他觉得合适的时候保留或删除。我不确定你的意思,但两个文件都有相同的键(
A
B,
C
)。使用多字段sperator,如果第二个文件中有
:`会不会有问题?@jeanrjc Yes会有问题。在示例数据中,您似乎没有清楚地列出两个文件中都存在多个字段分隔符。我建议您添加一些真正代表您的文件的示例数据。好的,您能解释一下
$2在一个中吗?一个选项,不一定是最好的,是预处理其中一个文件,使其具有与另一个相同的分隔符,然后使用单个分隔符“自然”处理它们。可能是@jww的重复,但不是。这个问题是关于如何为不同的文件(不是单个文件)使用不同的分隔符,答案是不同的。啊,很好,这就是我想要的!是的,这就是文件列表中设置变量的目的-为不同的文件以不同的方式填充初始值。对于其他内容,最好先使用
-v
设置它们。没有意识到可以使用FS来代替-F
$ awk -F"[: ]" 'NR==FNR{a[$1]=$2;next}$2 in a{print $2,a[$2],$1}' f1 f2
A 10 100
B 5 50
C 12 42
awk '...' FS=":" file1 FS=" " file2
$ awk 'NR==FNR{a[$1]=$2;next}{print $2,a[$2],$1}' FS=":" file1 FS=" " file2
A 10 100
B 5 50
C 12 42