【发布时间】:2014-06-01 23:49:33
【问题描述】:
为一个看似愚蠢的问题道歉。但我花了一整天的时间试图弄清楚它,它把我逼疯了。我正在尝试编写一个看似简单的 bash 脚本,该脚本将从 ls 获取目录中的文件列表,使用 sed 替换部分文件名,从列表中获取唯一名称并将它们传递给某个命令。像这样:
inputs=`ls *.ext`
echo $inputs
test1_R1.ext test1_R2.ext test2_R1.ext test2_R2.ext
现在我想通过 sed 将 1.ext 和 2.ext 替换为 * 以获得 test1_R* 等。然后我想通过运行 sort -u 删除生成的重复项以到达以下 $outputs变量:
echo $outputs
test1_R* test2_R*
然后将它传递给一个命令,就像这样
cat $outputs
我可以在命令行中做这样的事情:
ls *.ext | sed s/..ext/\*/g | sort -u
但是,如果我尝试将上述内容分配给脚本中的变量,它只会返回 ls 的输出。我尝试了几种方法来做到这一点:在脚本中包含整个管道。分别运行每个命令并将其分配给一个变量,然后将该变量传递给下一个命令并将输出写入文件,然后将文件传递给下一个命令。但到目前为止,这些都没有达到我的目标。我认为我的问题在于(除了关于 bash 脚本的一般无知)无法在脚本中的变量上运行 seq 。关于如何在 sed 中将变量传递给模式或替换字符串似乎有很多建议,但它们似乎都将文件作为输入。但我知道这可能不是正确的做法。因此,如果有人能提出一种优雅的方式来实现我正在尝试的目标,我将不胜感激。
非常感谢!
2014 年 2 月 6 日更新
您好 Barmar,感谢您的回答。不能说它解决了问题,但它有助于精确定位它。似乎问题在于我使用星号。我不得不说,我很困惑。我得到的实际文件名是:
test1_R1.fastq.gz test1_R2.fastq.gz test2_R1.fastq.gz test2_R2.fastq.gz
如果我使用您建议的代码,在我看来这是正确的做法:
ins=$(ls *.fastq.gz | sed 's/..fastq.gz/\*/g' | sort -u)
Sed 似乎什么也没做,我得到了 ls: 的输出:
test1_R1.fastq.gz test1_R2.fastq.gz test2_R1.fastq.gz test2_R2.fastq.gz
现在,如果我用其他任何东西替换那个反斜杠,sed 就可以工作,但它也会返回我放在星号前面(或后面)的任何字符:
ins=$(ls *.fastq.gz | sed 's/..fastq.gz/"*/g' | sort -u)
test1_R"* test2_R"*
这很奇怪,但我当然可以在星号前面放一个“R”,然后在搜索模式字符串中替换 R,对吧?错误的!如果我这样做,无论哪种方式:'s/R..fastq.gz/R*/g''s/...fastq.gz/R*/g''s/[A-Z]..fastq.gz/R*/g'我回到原来的名字!即使我最终得到test1_RR* test2_RR* 之类的东西并尝试再次通过sed 运行它并将"_R" 替换为"_" 或"RR" 替换为"R",我没有运气,我又回到了原来的名字。然而我可以替换文件名的其余部分没问题,只是不要让我test1_R*我需要。
我有一种感觉,我应该以某种非常聪明的方式摆脱这种 *,但我尝试过的任何方法似乎都不起作用。再次感谢您的帮助!
【问题讨论】: