![一个 Bash 命令,用于遍历目录中的文件列表,查找重复的 1-9 号文件,并将它们连接成一个新文件](https://linux22.com/image/1470138/%E4%B8%80%E4%B8%AA%20Bash%20%E5%91%BD%E4%BB%A4%EF%BC%8C%E7%94%A8%E4%BA%8E%E9%81%8D%E5%8E%86%E7%9B%AE%E5%BD%95%E4%B8%AD%E7%9A%84%E6%96%87%E4%BB%B6%E5%88%97%E8%A1%A8%EF%BC%8C%E6%9F%A5%E6%89%BE%E9%87%8D%E5%A4%8D%E7%9A%84%201-9%20%E5%8F%B7%E6%96%87%E4%BB%B6%EF%BC%8C%E5%B9%B6%E5%B0%86%E5%AE%83%E4%BB%AC%E8%BF%9E%E6%8E%A5%E6%88%90%E4%B8%80%E4%B8%AA%E6%96%B0%E6%96%87%E4%BB%B6.png)
我有一个包含一堆文件的目录,例如:
ExperimentA_Rep1.bed
ExperimentA_Rep2.bed
ExperimentA_Rep3.bed
ExperimentB_Rep1.bed
ExperimentD_Rep1.bed
ExperimentC_Rep1.bed
ExperimentC_Rep2.bed
.
.
.
ExperimentZ_Rep5.bed
我需要扫描目录中的文件名,并将来自同一实验但不同重复的文件连接成一个新文件。
IE
cat ExperimentA_Rep1.bed ExperimentA_Rep2.bed > ExperimentA_merged.bed
如果实验只有 1 个重复,它不应该做任何事情。但我无法对此进行硬编码,它需要适用于任何实验数据集。
如果我运行一个 python 脚本那就没问题了。
答案1
尝试这个 shell 脚本:
for f in *Rep1.bed
do
cat "${f%Rep1.bed}"*.bed >"$f.merged"
done
怎么运行的
示例中的每个实验都有一个以 结尾的文件Rep1.bed
。要查找该实验中的所有文件,我们可以使用 glob ${f%Rep1.bed}"*.bed
。然后,这些文件将连接到单个文件。每个实验都会重复此操作。
该表格${f%Rep1.bed}
是后缀删除的示例。它获取变量f
并从末尾删除符号后面的任何模式%
。例如,让我们创建一个 shell 变量:
$ f=ExperimentC_Rep2.bed
$ echo "${f}"
ExperimentC_Rep2.bed
现在,让我们.bed
从末尾删除:
$ echo "${f%.bed}"
ExperimentC_Rep2
或者,正如我们这里需要的那样,我们可以删除一个较长的字符串Rep2.bed
:
$ echo "${f%Rep2.bed}"
ExperimentC_
上面剩下的是删除了副本编号的实验名称。我们可以使用它来选择与该实验名称关联的所有副本文件,方法是使用 glob"${f%Rep1.bed}"*.bed
作为一行
以交互方式运行代码时,有时将其作为一行运行会更容易。上面的代码作为一行运行,如下所示:
for f in *Rep1.bed; do cat "${f%Rep1.bed}"*.bed >"$f.merged"; done
仅为 2 个或更多复制体的实验制作合并文件
有些实验只有一个副本(*_Rep1.bed
)。其他的则有多个:_Rep1.bed
,_Rep2.bed
,...如果我们只想选择具有两个或更多副本的文件,我们可以仅选择Rep2
存在的文件:
for f in *Rep2.bed; do cat "${f%Rep2.bed}"*.bed >"$f.merged"; done