Jan*_*ana 34 shell-script text-processing
我有多个文件,它们具有相同的标头和下面的不同向量。我需要连接所有这些,但我只想连接第一个文件的标题,我不希望连接其他标题,因为它们都是相同的。
例如:file1.txt
<header>INFO=<ID=DP,Number=1,Type=Integer>
<header>INFO=<ID=DP4,Number=4,Type=Integer>
A
B
C
Run Code Online (Sandbox Code Playgroud)
文件2.txt
<header>INFO=<ID=DP,Number=1,Type=Integer>
<header>INFO=<ID=DP4,Number=4,Type=Integer>
D
E
F
Run Code Online (Sandbox Code Playgroud)
我需要输出
<header>INFO=<ID=DP,Number=1,Type=Integer>
<header>INFO=<ID=DP4,Number=4,Type=Integer>
A
B
C
D
E
F
Run Code Online (Sandbox Code Playgroud)
我可以在 R 中编写脚本,但我需要在 shell 中使用它?
xea*_*its 52
另一种解决方案,类似于cat+grep上面的“ ”,使用tail和head:
将第一个文件的标题写入输出:
head -2 file1.txt > all.txt
Run Code Online (Sandbox Code Playgroud)
--head -2获取文件的前 2 行。
添加所有文件的内容:
tail -n +3 -q file*.txt >> all.txt
Run Code Online (Sandbox Code Playgroud)
--n +3使得tail打印线从3日到年底,
-q告诉它不打印与文件名(读头man),
>>增加了文件,而不是覆盖它>。
并且确保您可以将两个命令放在一行中:
head -2 file1.txt > all.txt; tail -n +3 -q file*.txt >> all.txt
Run Code Online (Sandbox Code Playgroud)
或者而不是;放在&&它们之间进行成功检查。
Gil*_*il' 21
如果您知道如何在 R 中完成,那么一定要在 R 中完成。使用经典的 unix 工具,这最自然地在 awk 中完成。
awk '
FNR==1 && NR!=1 { while (/^<header>/) getline; }
1 {print}
' file*.txt >all.txt
Run Code Online (Sandbox Code Playgroud)
awk 脚本的第一行与文件的第一行 ( FNR==1)匹配,除非它也是所有文件的第一行 ( NR==1)。当满足这些条件时,将while (/^<header>/) getline;执行表达式,这会导致 awk 继续读取另一行(跳过当前行),只要当前行与 regexp 匹配^<header>。awk 脚本的第二行打印除了先前跳过的行之外的所有内容。
尝试这样做:
$ cat file1.txt; grep -v "^<header" file2.txt
<header>INFO=<ID=DP,Number=1,Type=Integer>
<header>INFO=<ID=DP4,Number=4,Type=Integer>
A
B
C
D
E
F
Run Code Online (Sandbox Code Playgroud)
:
array=( files*.txt )
{ cat ${array[@]:0:1}; grep -v "^<header" ${array[@]:1}; } > new_file.txt
Run Code Online (Sandbox Code Playgroud)
这是一种bash数组切片技术。