为一个看似无聊的问题道歉。但是我花了一整天的时间试图解决这个问题,这让我感到震惊。我正在尝试编写一个看似简单的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来删除生成的重复项以到达以下$ output变量:
echo $outputs
test1_R* test2_R*
并将其传递给命令,就像这样
cat $outputs
我可以在命令行中执行以下操作:
ls *.ext | sed s/..ext/\*/g | sort -u
但是如果我尝试将上面的内容分配给脚本中的变量,它只返回ls的输出。我尝试了几种方法:在脚本中包含整个管道。分别运行每个命令并将其分配给变量,然后将该变量传递给下一个命令并将输出写入文件,然后将文件传递给下一个命令。但到目前为止,没有一个能够实现我的目标。我认为我的问题在于(除了一般无知的bash脚本)无法在脚本中的变量上运行seq。关于如何在sed中将变量传递给模式或替换字符串似乎有很多建议,但它们似乎都将文件作为输入。但我明白,无论如何,这可能不是正确的做法。因此,如果有人能够提出一种优雅的方式来实现我想要的东西,我真的很感激。
非常感谢!
2014年2月2日更新
嗨巴马尔,谢谢你的回答。不能说它解决了这个问题,但它帮助指出了它。似乎问题在于我使用星号。我不得不说,我很困惑。我得到的实际文件名是:
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会起作用,但它也会返回我在asteriks前面(或之后)放置的任何字符:
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*
我需要。
我有一种感觉,我应该以一种非常聪明的方式逃避*,但我尝试过的任何东西似乎都没有用。再次感谢您的帮助!
答案 0 :(得分:1)
这是在变量中捕获整个管道的结果的方法:
var=$(ls *.ext | sed s/..ext/\*/g | sort -u)