抽象:
适用于名称为“奇数”(包括换行)的文件。
set -- *snp* ; echo "$#" # change positional arguments
count=$(printf 'x%.0s' *snp*); echo "${#count}" # most shells
printf -v count 'x%.0s' *snp*; echo "${#count}" # bash
描述
因为一个简单的glob会匹配每个文件名snp的名称echo *snp*,在这种情况下,一个简单的名字就足够了,但是要真正表明只有三个文件匹配,我将使用:
$ ls -Q *snp*
"Codigo-0275_tdim.snps.tsv" "foo * bar\tsnp baz.tsv" "S134_tdim.snps.tsv"
剩下的唯一问题是对文件进行计数。是的,grep是一个常见的解决方案,是的,用新行数wc -l也是一个常见的解决方案。请注意,grep -c(计数)实际上是计算一个snp字符串被匹配的次数,并且,如果一个文件名的名称中有多个snp字符串,则该计数将是不正确的。
我们可以做得更好。
一种简单的解决方案是设置位置参数:
$ set -- *snp*
$ echo "$#"
3
为了避免更改位置参数,我们可以将每个参数转换为一个字符并输出结果字符串的长度(对于大多数shell):
$ printf 'x%.0s' *snp*
xxx
$ count=$(printf 'x%.0s' *snp*); echo "${#count}"
3
或者,在bash中,避免使用subshell:
$ printf -v count 'x%.0s' *snp*; echo "${#count}"
3
档案清单
文件列表(来自原始问题,其中一个带有换行符):
a='
Codigo-0275_tdim.matches.tsv
Codigo-0275_tdim.snps.tsv
FloragenexTdim_haplotypes_SNp3filter17_single.tsv
FloragenexTdim_haplotypes_SNp3filter17.tsv
FloragenexTdim_SNP3Filter17.fas
S134_tdim.alleles.tsv
S134_tdim.snps.tsv
S134_tdim.tags.tsv'
$ touch $a
touch $'foosnp\nbar.tsv'
那将有一个文件,中间有一个换行符:
f o o
s n p \n
b a r
. t s v
并测试glob扩展:
$ touch $'foo * bar\tsnp baz.tsv'
这将添加一个星号,如果不加引号,则将扩展到整个文件列表。