我想用另一个文本文件中的相应行替换文本文件中的一行。
文件1的内容:
>line1
GGG
>line2
AAA
>line3
TTT
>line4
CCC
>line5
CAT
文件2的内容:
>name.A
CTGG
>name.B
GACC
>name.C
CTGG
>name.D
GGAA
>name.E
GCTA
两个文件中的行数相同。最终文件应如下所示:
>name.A
GGG
>name.B
AAA
>name.C
TTT
>name.D
CCC
>name.E
CAT
我已经寻找一种解决方案,但似乎找不到。我确实尝试了以下操作:
awk 'FNR==NR {data[FNR]=$0; next} (FNR%2==1){$0=data[FNR]}1' < File1 < File2
但什么也没发生。
任何帮助将非常感激!
答案1
$ awk 'NR==FNR{a[NR]=$0; next} {print (FNR%2 ? $0 : a[FNR])}' file1 file2
>name.A
GGG
>name.B
AAA
>name.C
TTT
>name.D
CCC
>name.E
CAT
除了更简洁(并且有效:-))之外,上述方法比您所采用的方法更有效,因为:
- 它没有分配给 $0,因此不会强制 awk 将记录重新分割为字段
1
在决定是否打印之前,它不会对每一行测试第二个条件 ( )。
另外 - 不要使用输入重定向来打开 awk 文件,因为它不适用于多个文件(正如您所发现的)并且会剥夺您检查 FILENAME 的能力。
答案2
您可以通过以下方式执行 pbm:首先调用paste
实用程序以制表符分隔的方式排列行,然后调用sed
编辑器执行手术以获得所需的数据输出:
$ paste File1 File2 | sed -ne '
s/>.*\t//p
s/\t.*//p
'
输出
>name.A
GGG
>name.B
AAA
>name.C
TTT
>name.D
CCC
>name.E
CAT
注意:Posix sed 无法识别\t
代表制表符的转义序列。我只是用它来突出显示一个 otw 不可见字符。因此,您可以放置一个文本制表符来代替 \t。
有了Perl
实用性,它就成了一句话:
$ perl -pe '$_=($_,$,.<STDIN>)[$.%2]' File1 < File2
答案3
您的 awk 命令基本上是正确的 - 如果您删除无关的重定向并交换文件顺序,它将起作用:
$ awk 'FNR==NR {data[FNR]=$0; next} (FNR%2==1){$0=data[FNR]}1' File2 File1
>name.A
GGG
>name.B
AAA
>name.C
TTT
>name.D
CCC
>name.E
CAT
或者,使用 GNU sed 和支持进程替换的 shell:
$ sed -e '2~2{R /dev/stdin' -e 'd}' File2 < <(sed '1~2d' File1)
>name.A
GGG
>name.B
AAA
>name.C
TTT
>name.D
CCC
>name.E
CAT
解释:
sed '1~2d' File1
从 File1 中删除奇数行< <(...)
通过 stdin 输入结果sed -e '2~2{R /dev/stdin' -e 'd}' File2
一次从 stdin 读取一行并将其排队插入到 File2 的下一个偶数行之后;然后删除偶数行
答案4
尝试使用 sed 命令,效果很好
for ((i=2;i<=10;i++));do j=`sed -n ''$i'p' f1`; k=`echo $j|sed -r "s/\s+//g"`;sed -i ""$i"s/.*/"$k"/g" f2;i=$(($i+1)); done
输出
>name.A
GGG
>name.B
AAA
>name.C
TTT
>name.D
CCC
>name.E
CAT