AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 781678
Accepted
Matteo
Matteo
Asked: 2024-08-10 16:13:42 +0800 CST2024-08-10 16:13:42 +0800 CST 2024-08-10 16:13:42 +0800 CST

基于文件大小的命令执行失败,没有明显问题

  • 772

我正在为一个小型管道处理数组作业,碰巧需要一种根据文件大小执行特定命令的方法。我找到了这篇文章和类似的文章,它们描述了如何做到这一点。目前我正在使用以下内容:

find $d/*.fasta -size +100M -exec sh -c '
     chromap -i -r $1 -o $1.index

     chromap --preset hic -x $1.index -r $1 -1 $d/hi-c/${ID}_1.fq.gz -2 $d/hi-c/${ID}_2.fq.gz --SAM -o /dev/stdout -t 48 | \
         samtools view -bS -@ 48 | samtools sort -n -@ 48 | samtools view -h | sed -e "s/\/.//" | samtools view -bS -o ${ID}.bam -@ 48
     ' sh {} \;

除了生物信息和使用的工具都有效之外,它似乎只执行了第一个命令行 — chromap -i -r $1 -o $1.index。然后,出于某种原因,一旦进入第二组指令,脚本就会返回以下内容:

找不到序列文件 /hi-c/_1.fq.gz

这表明它不知道我迄今为止成功使用的环境变量,或者它当时无法计算两个以上的操作?我没有任何线索……我还尝试了一些更简单的东西,例如

mkdir $d/scaffolding
find $d/*.fasta -size +100M -exec sh -c '
     chromap -i -r $1 -o $1.index && mv $1 $1.index $d/scaffolding
' sh {} \;

但 Bash 抱怨:mv: the destination '/scaffolding' is not a directory。

我应该怎么做才能让其中一个(或两个)工作?我是否遗漏了什么,如果有人对这个问题有一些见解,请告诉我!提前致谢。

bash
  • 2 2 个回答
  • 315 Views

2 个回答

  • Voted
  1. Best Answer
    Stéphane Chazelas
    2024-08-10T16:44:01+08:002024-08-10T16:44:01+08:00
    export d ID
    find -H "$d"/*.fasta -prune -size +100M -exec bash -o pipefail -c '
      ret=0
      for file do
        chromap -i -r "$file" -o "$file.index" &&
          chromap --preset hic \
                  -x "$file.index" \
                  -r "$file" \
                  -1 "$d/hi-c/${ID}_1.fq.gz" \
                  -2 "$d/hi-c/${ID}_2.fq.gz" \
                  --SAM -o /dev/stdout -t 48 |
            samtools view -bS -@ 48 |
            samtools sort -n -@ 48 |
            samtools view -h |
            sed "s:/.::" |
            samtools view -bS -o "${ID}.bam" -@ 48 ||
          ret=$?
        done
        exit "$ret"
      ' bash {} +
    

    解决几个问题:

    • 除非你导出$d,否则$ID启动sh者find将无法看到它们
    • 如果没有-H,对于那些fasta符号链接的文件,find将检查符号链接的大小,而不是 fasta 文件的大小
    • 如果没有-prune,对于那些目录,find将深入其中。您可能希望使用 将它们全部排除,! -type d或者仅使用 包含常规文件-type f(包括指向 的常规文件的符号链接-H)。添加这些检查并不能消除对 的需求-prune(-maxdepth 0如果使用 GNUfind或兼容)。
    • 您忘记引用参数扩展了。在 zsh 中您可以不用引用,但在 sh 和 bash 中不行。
    • 在运行下一个命令之前,您没有检查命令的状态。在这里,我添加了选项,pipefail以便如果任何命令失败,管道将返回失败。这现在是一个标准sh选项,但有些sh实现dash仍然不支持它,所以我用 替换了,sh尽管bash您可以使用任何其他sh支持的实现pipefail。
    • 单引号内有单引号,这意味着 位于s/\/.//引号外,这意味着它与 相同,s//.//这不是有效sed代码。这里我们使用双引号作为内引号,并将 切换/为:分隔符以避免必须转义/。请注意 会s:/.::删除 的第一个匹配项,/后跟任何单个字符且没有任何内容。从/.字面上删除,即s:/\.::和s:/\.::g删除所有匹配项。
    • 使用-exec sh ... {} ';',您将为sh每个文件运行一个,并且不会报告任何失败。 用 替换-exec sh ... {} +可解决两者的问题。

    如果您可以切换到 zsh,那么大多数问题就可以轻松避免。

    set -o pipefail
    errors=0
    for file (*.fasta(N-.LM+100)) {
      chromap -i -r $file -o $file.index &&
          chromap --preset hic \
                  -x $file.index \
                  -r $file \
                  -1 $d/hi-c/${ID}_1.fq.gz \
                  -2 $d/hi-c/${ID}_2.fq.gz \
                  --SAM -o /dev/stdout -t 48 |
            samtools view -bS -@ 48 |
            samtools sort -n -@ 48 |
            samtools view -h |
            sed 's:/.::' |
            samtools view -bS -o ${ID}.bam -@ 48 ||
          (( error++ ))
    }
    
    • zsh 没有 Bourne shell 的缺陷,即未加引号的扩展需要进行 split+glob,所以您可以省略引号。
    • zsh globs 具有 的大部分find功能内置函数,因此您不必将 shell globs (您的*.fasta)与相结合find。
    • 这意味着,不需要嵌套引号,这意味着不需要运行单独的 shell 并需要向其导出变量,这意味着我们可以更轻松地返回错误计数。
    • zsh 确实支持pipefail(与某些实现相反sh)。
    • 8
  2. Kusalananda
    2024-08-10T16:39:46+08:002024-08-10T16:39:46+08:00

    您假设内联脚本中的几个 shell 变量sh -c是通过环境继承的。它们是d和ID。如果 shell在find调用 之前没有将它们导出到环境中,则sh -c脚本将看不到它们,并将用空字符串代替它们。

    因此,在拨打电话之前find,请确保您已

    export d ID
    

    ...在你的脚本中。

    find或者,在调用命令时设置它们,如下所示:

    d=$d ID=$ID find "$d"/*.fasta -size +100M -exec ...
    

    还要记得对脚本中的所有变量扩展加上双引号:

    export d ID
    
    find "$d"/*.fasta -size +100M -exec sh -c '
        chromap -i -r "$1" -o "$1.index"
    
        chromap --preset hic -x "$1.index" -r "$1" -1 "$d/hi-c/${ID}_1.fq.gz" -2 "$d/hi-c/${ID}_2.fq.gz" --SAM -o /dev/stdout -t 48 |
        samtools view -bS -@ 48 |
        samtools sort -n -@ 48 |
        samtools view -h | sed -e 's/\/.//' |
        samtools view -bS -o "${ID}.bam" -@ 48' sh {} \;
    
    • 3

相关问题

  • 通过命令的标准输出以编程方式导出环境变量[重复]

  • 从文本文件传递变量的奇怪问题

  • 虽然行读取保持转义空间?

  • `tee` 和 `bash` 进程替换顺序

  • 运行一个非常慢的脚本直到它成功

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    模块 i915 可能缺少固件 /lib/firmware/i915/*

    • 3 个回答
  • Marko Smith

    无法获取 jessie backports 存储库

    • 4 个回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    user12345 无法获取 jessie backports 存储库 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl 为什么大多数 systemd 示例都包含 WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve