使用 sed/awk/etc 将一个文本文件中的奇数行替换为另一个文本文件中相应的奇数行

使用 sed/awk/etc 将一个文本文件中的奇数行替换为另一个文本文件中相应的奇数行

我想用另一个文本文件中的相应行替换文本文件中的一行。

文件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

除了更简洁(并且有效:-))之外,上述方法比您所采用的方法更有效,因为:

  1. 它没有分配给 $0,因此不会强制 awk 将记录重新分割为字段
  2. 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

相关内容