首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在shell中填充带有文件名的变量

如何在shell中填充带有文件名的变量
EN

Stack Overflow用户
提问于 2017-07-28 23:59:37
回答 4查看 130关注 0票数 0

我有一个包含一些文件的文件夹,我正在尝试用逗号分隔的文件名填充一个变量。这就是我到目前为止尝试过的

包含所需文件的文件夹

代码语言:javascript
复制
examples/NMD_DBL1.tiny.bam
examples/NMD_DBL2.tiny.bam
examples/NMD_WT1.tiny.bam
examples/NMD_WT2.tiny.bam
examples/SRR2240277.bam
examples/SRR2240278.bam

当我运行这个程序时,我得到以下信息

代码语言:javascript
复制
for i in examples/*bam; do echo $i | cut -d "/" -f 2 | tr "\n" ","; done
NMD_DBL1.tiny.bam,NMD_DBL2.tiny.bam,NMD_WT1.tiny.bam,NMD_WT2.tiny.bam,SRR2240277.bam,SRR2240278.bam,[upendra_35@rogue python]$ 

当我试图将输出赋值给一个变量时,我只得到一个文件名,后面跟着逗号。

代码语言:javascript
复制
for i in examples/*bam; do new=$(echo $i | cut -d "/" -f 2 | tr "\n" ","); done
echo $new
SRR2240278.bam,

如何将所有文件都放入变量new中,用逗号分隔如下?

new=NMD_DBL1.tiny.bam,NMD_DBL2.tiny.bam,NMD_WT1.tiny.bam,NMD_WT2.tiny.bam,SRR2240278.bam 2240277.bam,SRR2240278.bam 2240278.bam

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2017-07-29 00:40:00

在巴什

请注意,只有当您的脚本使用bash而不是sh运行时,才能保证下面的脚本工作;确保它以#!/usr/bin/env bash#!/usr/bin/env bash或类似的方式开始。

要用文件列表填充数组,请执行以下操作:

代码语言:javascript
复制
files=( examples/*.bam )     # put your list of names into an array
files=( "${files[@]##*/}" )  # remove directory names from each

然后将该数组的内容放入逗号分隔的字符串中:

代码语言:javascript
复制
IFS=,
files_str=${files[*]}

...or,如果您不想修改IFS

代码语言:javascript
复制
printf -v files_str '%s,' "${files[@]}"  # expand the format string '%s,' for each
files_str=${files_str%,}                 # remove the last comma

在任何POSIX外壳中

除了一个:参数列表之外,基线POSIX shell中不保证数组。如果不想覆盖全局参数列表,则可以生成具有函数的作用域参数列表。因此:

代码语言:javascript
复制
comma_separated_file_list() {
  # check that the first argument exists
  # if it doesn't, then the glob that generated our list came up empty
  [ -e "$1" ] || [ -L "$1" ] || return

  # consume arguments one at a time, append a "," after each that isn't last.
  while [ "$#" -gt 0 ]; do
    if [ "$#" -gt 1 ]; then
      printf '%s,' "${1##*/}"
    else
      printf '%s' "${1##*/}"
    fi
    shift
  done
}

new=$(comma_separated_file_list examples/*.bam)

这样做的好处是,如果不存在examples/*.bam的匹配项,则变量new将为空( comma_separated_file_list函数将返回错误的退出状态,您可以继续使用该状态)。

票数 1
EN

Stack Overflow用户

发布于 2017-07-29 00:29:20

我认为把整个for循环的输出分配给new应该有效,

new = $(for i in examples/*bam; do echo $i | cut -d "/" -f 2 | tr "\n" ","; done) echo $new

票数 0
EN

Stack Overflow用户

发布于 2017-07-29 00:49:38

代码语言:javascript
复制
files=$(printf "%s," *.bam)   # files a trailing comma
files=${files%,}              # ... but not any more

这里使用的技巧是,printf具有这样的属性:如果它有比转换说明符更多的参数,它会通过格式字符串重复附加参数。强制性演示:

代码语言:javascript
复制
$ printf "(%s - %s)\n" a b c d e f g h
(a - b)
(c - d)
(e - f)
(g - h)

因此,使用"%s,",我们可以遍历参数并在每个参数中添加一个逗号;但是,当然,我们希望逗号分开,而不是终止。普通的旧POSIX ${var%pat}扩展解决了这个问题。

如果*.bam不匹配呢?然后files最终得到了*.bam;检查一下可能是个好主意。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45383904

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档