【问题标题】:How to execute command without using the do command twice in the loop如何在循环中不使用do命令两次执行命令
【发布时间】:2022-01-21 22:11:07
【问题描述】:

这些是我的文件

KIMS2021-01_R1.fastq.gz  KIMS2021-05_R1.fastq.gz  SRR1734376_1.fastq.gz  SRR6006897_1.fastq.gz  SRR6006901_1.fastq.gz  SRR6006905_1.fastq.gz
KIMS2021-01_R2.fastq.gz  KIMS2021-05_R2.fastq.gz  SRR1734376_2.fastq.gz  SRR6006897_2.fastq.gz  SRR6006901_2.fastq.gz  SRR6006905_2.fastq.gz
KIMS2021-02_R1.fastq.gz  KIMS2021-06_R1.fastq.gz  SRR1734377_1.fastq.gz  SRR6006898_1.fastq.gz  SRR6006902_1.fastq.gz  SRR6006906_1.fastq.gz
KIMS2021-02_R2.fastq.gz  KIMS2021-06_R2.fastq.gz  SRR1734377_2.fastq.gz  SRR6006898_2.fastq.gz  SRR6006902_2.fastq.gz  SRR6006906_2.fastq.gz
KIMS2021-03_R1.fastq.gz  SRR1734374_1.fastq.gz    SRR6006895_1.fastq.gz  SRR6006899_1.fastq.gz  SRR6006903_1.fastq.gz
KIMS2021-03_R2.fastq.gz  SRR1734374_2.fastq.gz    SRR6006895_2.fastq.gz  SRR6006899_2.fastq.gz  SRR6006903_2.fastq.gz
KIMS2021-04_R1.fastq.gz  SRR1734375_1.fastq.gz    SRR6006896_1.fastq.gz  SRR6006900_1.fastq.gz  SRR6006904_1.fastq.gz
KIMS2021-04_R2.fastq.gz  SRR1734375_2.fastq.gz    SRR6006896_2.fastq.gz  SRR6006900_2.fastq.gz  SRR6006904_2.fastq.gz

为了获得每对的统一文件名,我从上一个问题中得到了这个答案 这是这个

for i in $(echo *.fastq*.gz); do echo ${i%_*}; done | uniq

获得统一文件名后我想使用的最终命令

for i in $(ls *.fastq*.gz); do echo ${i%_*}; done | uniq; do STAR --runMode alignReads --outSAMtype BAM SortedByCoordinate --runThreadN 30 --genomeDir /run/media/punit/data3/Santosh_star_index --readFilesIn  <(gunzip -c ${i}_R1.fastq.gz ${i}_R2.fastq.gz ) --outFileNamePrefix ${i%};done

现在我明白我不能在一个循环中使用do 两次

如何在不使用do 两次的情况下将统一文件名传递给我的命令

【问题讨论】:

  • 我看不出使用echo 的意义。它不仅会创建一个不必要的子进程,如果您的文件名带有嵌入的空格,它甚至会产生错误的结果。你为什么不简单地做一个for i in *.fastq*.gz
  • do STAR ... 没有意义。那里没有语法错误吗?
  • 是的,这就是为什么问题..我必须使用文件名传递给对准器问题是由于不统一的文件名.如果它是像只有 SRR 这样的模式我很高兴去用命令
  • user1934428 在我之前的问题中,我得到了 echo 的建议,因为它比 ls 更安全
  • 你不应该使用ls是正确的,但是用另一个废话代替一个废话也没有帮助。对于echols,您会遇到包含空格或换行符的文件名问题。所以不要这样做。

标签: loops shell for-loop


【解决方案1】:

我之前的问题是这样的

首先让我们修复它!不要这样做:

for i in $(anything); do

只要做:

for i in *.fastq*.gz; do

如何将统一文件名传递给我的命令

Shell 最重要的是与 管道 | 一起使用。一个命令的输出是另一个命令的输入——就像在你的管道中一样,for 循环的输出是uniq 的输入。

读取 uniq 的输出。

for i in *.fastq*.gz; do echo "${i%_*}"; done |
   uniq |
   while IFS= read -r file; do stuff with "$file"; done

使用 shellcheck.net 检查您的脚本。见https://mywiki.wooledge.org/BashFAQ/001

作为一名生物学家,我确实很痛苦地挖掘脚本的基本细微差别,我的简单解决方案是,如果我将它们作为两组运行

当然!我经常在交互式脚本编写时这样做。

tmp=$( for i in *.fastq*.gz; do echo "${i%_*}"; done )
tmp=$( uniq <<<"$tmp" )   # or tmp=$( echo "$tmp" | uniq )
tmp=$( echo "$tmp" | while IFS= read -r file; do stuff with "$file"; done )
echo "$tmp"

记住qoutes "&lt;&lt;&lt;"stuff" 的作用类似于&lt;file - 将"stuff" 的内容输入到命令的输入中,与echo "$tmp" | 的作用相同。

【讨论】:

  • 所以在这里你已经使用了两次它只有在与'while'一起使用时才有效,请原谅我的无知
  • 嗯,是的,关键字do 必须以forwhile 开头,它必须是for ....; dowhile ....; do。每个管道元素都是一个单独的命令,forwhile(以及 ifcaseuntil 和组 (...) {...})算作一个命令。 ( a=example; echo $a; ) | ( read var; echo "This is $var" )
  • @PesKchan :只做词法分析,你可能是对的,但关键是涉及到两个循环,bash的设计者以他们无限的智慧做出了决定,每个循环(forwhile)必须包含单词 do。您可能想搜索仅包含单个循环的解决方案,尽管我没有看到任何好处。
  • 作为一名生物学家,我确实很痛苦地挖掘脚本的基本细微差别,我的简单解决方案是,如果我将它们作为两组运行..
  • if i run the them as two sets 更新
猜你喜欢
  • 1970-01-01
  • 2014-06-06
  • 2014-01-27
  • 2012-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-07
  • 1970-01-01
相关资源
最近更新 更多