【问题标题】:Cat more files together in a directory by similar names用相似的名称将更多文件放在一个目录中
【发布时间】:2016-06-27 20:33:55
【问题描述】:

我在同一个目录下有如下五个文件(名称以.bed and startchromosomeand have numbers such as1-5`结尾嵌入在中间;显示一行内容或每个文件):

染色体1-5.床

chromosome1     1   21

染色体1-2.床

chromosome1     7   30

chromosome1-9.bed

chromosome1     9   75

染色体2-1.床

chromosome2     8   50

chromosome2-5.bed

chromosome2     6   23

并且我尝试将以相同编号开头的文件归类到一个文件中(因此所有在1-5 等中以1 开头的文件)。

预期输出:

chromosome1.bed

chromosome1     1   21 
chromosome1     7   30
chromosome1     9   75

chromosome2.bed

chromosome2     8   50 
chromosome2     6   23

此时我尝试将目录中的任何文件与另一个文件名进行比较。

for i in /dir/*; do
    for j in /dir/*; do
        filename=$(basename "$i")
        filename2=$(basename "$j")
        if "$filename" != "$filename2";
        then cat "$i" "$j" > newfile
        fi
    done
done 

【问题讨论】:

  • 关于代码,您尝试将$filename 的内容作为带有参数="$filename2" 的命令执行。您想测试字符串,它使用[ 测试命令:if [ "$filename" != "$filename2" ]; then …; fi。请注意,命令名称 ([) 和最后一个参数 (]) 周围的空格是必需的。
  • 您怎么知道输出应该在chromosome1-2.bed 之前列出chomosome1-5.bed,或者排序无关紧要?有多少个不同的领先数字?你显示12;数字是个位数,还是可以是多位数?有前导零吗?与尾随数字类似——它们是单个数字,还是可以更长,并且使用前导零?文件名中除了.-_ 之外是否还有空格或其他非字母数字字符?目录中是否还有其他文件可以匹配chromosome*-*.bed
  • 文件名例如是染色体1-5.bed、染色体1-2.bed和染色体1-9.bed。我试着把它和染色体1.bed这个名字合二为一。我尝试了您的建议,但我收到消息 [*: command not found。我尝试在上面的代码中检查这两个文件是否不相同。
  • 你没有注意我显示的间距。
  • 测序并不重要,只是染色体后的第一个数字需要相同,这也可以是 chomosome31-5.bed 或 chomosome31-25.bed

标签: loops awk filenames cat


【解决方案1】:
awk '!/^---/ {fname= $1".bed"; print $0 > fname }' *-[0-9].bed

输出

cat chromosome1.bed

chromosome1     7   31
chromosome1     1   21
chromosome1     9   75


cat chromosome2.bed

chromosome2     8   50
chromosome2     6   23

此脚本跳过以---- 开头的行,并从剩余数据行的第一个字段创建文件名。我们将 ".bed" 附加到该名称,然后将 (>) 完整行写入指定文件。随着$1 的值发生变化,文件名也会发生变化。


编辑

由于您修改后的示例数据不再包含 ------ 行,因此可以进一步简化为

awk '{fname= $1".bed"; print $0 > fname }' *-[0-9].bed

无需过滤行---- 并且该测试已被删除。现在所有行都将自动打印到基于第一个字段创建的文件名中。


编辑 2

要允许将文件写入备用目录,一种方法是将目录名称作为变量传递,并将其预先附加到正在创建的fname,即

awk -v dir="NewDirectory" '{fname= dir "/" $1 ".bed"; print $0 > fname }' *-[0-9].bed

当然,"NewDirectory" 可能类似于 "$i/$j"

IHTH

【讨论】:

  • 可能是编辑问题。文件不以----开头。
  • @Babi :它仍然可以正常工作。但我会提供替代方案。祝你好运
  • 这在目录中工作,产生具有我想要的输出的新文件,但也有旧文件。我如何使用这条 awk 行并将输出保存在新目录中。我试试这个 awk '{fname= $1".bed"; print $0 > fname }' *-[0-9].bed > /newDirectory/ 但这不起作用。
  • @Babi :完成第二次编辑。离开一段时间。 IHTH
  • @EdMorton:啊!!非常感谢您的解释。我以前遇到过这种情况,我通常会想“我过去做过,为什么现在不起作用?......哦,我将使用一个变量来代替”。谢谢!!!
【解决方案2】:

虽然我喜欢 shelter 提出的 awk 解决方案,但 ma​​ke 是一种替代方案。这是 GNU make 的一个版本:

SRC = $(wildcard chromosome*-*.bed)
TGT = $(sort $(shell echo $(SRC) | sed -E 's/-[0-9]+[.]bed/.bed/g'))

all: $(TGT)

$(TGT): $(SRC)
    cat $(subst .bed,-*.bed,$@) > $@~
    mv $@~ $@

echo: 
    @ls $(SRC)
    @echo targets: $(TGT)

上面的每个目标都依赖于每个源,这显然是矫枉过正。如果您有很多文件或者它们经常更改,您可能希望生成正确的依赖关系。

优点:

  • 可以通过说例如重新生成特定文件make chromosome2.bed
  • 如果没有文件更改或添加,则跳过重新生成。
  • 出错时停止,不会部分完成生成的文件。

输出:

$ make
cat chromosome1-*.bed > chromosome1.bed~
mv chromosome1.bed~ chromosome1.bed
cat chromosome2-*.bed > chromosome2.bed~
mv chromosome2.bed~ chromosome2.bed

$ head  chromosome?.bed
==> chromosome1.bed <==
chromosome1     7   30
chromosome1     1   21
chromosome1     9   75

==> chromosome2.bed <==
chromosome2     8   50
chromosome2     6   23

【讨论】:

    【解决方案3】:

    为什么不使用通配符?

    cat chromosome1-* >> chromosome1.bed
    
    cat chromosome2-* >> chromosome2.bed
    

    chromosome2-* 将选择所有以染色体 2- 开头的文件,如果您手动执行的索引过多,您可以将其放入每个索引的循环中。

    【讨论】:

    • 我尝试使用:START=1 END=100 for (( c=$START; c&lt;=$END; c++ )) do cat /chromosome"$C"-* &gt;&gt; /chromosome"$C".bed done 但不起作用。我有同样的信息: cat: /chromosome-*: No such file or directory
    猜你喜欢
    • 2019-03-03
    • 1970-01-01
    • 2022-08-19
    • 2016-07-15
    • 2018-09-24
    • 1970-01-01
    • 2021-03-28
    • 2017-03-09
    • 1970-01-01
    相关资源
    最近更新 更多