我有一个包含如下文件的目录:
1_reads.fastq
2_reads.fastq
89_reads.fastq
42_reads.fastq
我想将这些文件名的逗号分隔列表提供给python程序中的命令,因此python命令的输入将是这样的:
program.py -i 1_reads.fastq,2_reads.fastq,89_reads.fastq,42_reads.fastq
此外,我想在python命令中使用文件名中的数字作为标签函数,这样输入将如下所示:
program.py -i 1_reads.fastq,2_reads.fastq,89_reads.fastq,42_reads.fastq -t s1,s2,s89,s42
重要的是文件名和标签ID的顺序相同。
答案 0 :(得分:2)
试试这个:
program.py $(cd DIR && var=$(ls) && echo $var | tr ' ' ',')
这会将$(..)中te命令行返回的字符串传递给program.py。
该命令行将:在您的目录中输入,运行ls将输出存储在变量中,这将删除换行符替换空格,并且它不会添加尾随空格。然后将该变量回应给' tr'这会将空格转换为逗号。
答案 1 :(得分:2)
首先:这是一个非常糟糕的调用约定。不要使用它。
但是,如果您正在使用其他人编写的软件,那已经将该约定记录在......
中#!/bin/bash
IFS=, # use comma as separator
files=( [[:digit:]]*_* )
[[ -e $files || -L $files ]] || { echo "ERROR: No files matching glob exist" >&2; exit 1; }
prefixes=( )
for file in "${files[@]}"; do
prefixes+=( "s${file%%_*}" )
done
# "exec" only if this is the last command in the script; remove otherwise
exec program.py -i "${files[*]}" -t "${prefixes[*]}"
这是如何运作的:
IFS=,
会导致${array[*]}
在每个展开的元素之间添加逗号。因此,展开${files[*]}
和${prefixes[*]}
会创建逗号分隔的字符串以及每个数组的内容。${file%%_*}
删除文件名中第一个_
之后的所有内容,只允许提取数字。[[ -e $files || -L $files ]]
实际上只测试该数组中的第一个元素是否存在(作为符号链接或其他方式);但是,如果扩展为形成数组的glob与任何文件匹配,则总是如此(除非在两行之间删除文件并调用)。答案 2 :(得分:2)
可以在纯Bash中轻松完成。确保从包含文件的目录中运行。
#!/bin/bash
shopt -s extglob nullglob
# Create an array of files
f=( +([[:digit:]])_reads.fastq )
# Check that there are some files...
if ((${#f[@]}==0)); then
echo "No files found. Exiting."
exit
fi
# Create an array of labels, directly from the array f:
# Remove trailing _reads.fastq
l=( "${f[@]%_reads.fastq}" )
# And prepend the letter s
l=( "${l[@]/#/s}" )
# Now the arrays f and l are good: check them:
declare -p f l
# To join the arrays, we'll use eval. Safe because the code is single-quoted!
IFS=, eval 'program.py -i "${f[*]}" -t "${l[*]}"'
注意。这里使用eval
非常安全,因为我们传递一个常量字符串(实际上这是一种不使用子shell或循环连接数组的惯用方法)。请勿修改命令,尤其是单引号。
感谢Charles Duffy说服我添加关于使用eval
的健康评论