이름에 특정 문자열이있는 디렉토리의 파일을 계산합니까? Codigo-0275_tdim.snps.tsv FloragenexTdim_haplotypes_SNp3filter17_single.tsv

다음 파일이 있습니다.

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

snp이름에 대소 문자를 구분 하는 파일 수를 세고 싶습니다 . 나는 사용하려고

grep -a 'snp' | wc -l   

그러나 나는 grep파일 내에서 검색 한다는 것을 깨달았습니다 . 파일 이름을 스캔하는 올바른 명령은 무엇입니까?



답변

snp파일 이름 을 검색 하시겠습니까? 다음과 같이 사용되는 간단한 쉘 글로브 (와일드 카드)입니다.

ls -dq *snp* | wc -l

-q의 버전이 ls인식하지 못하는 경우 플래그를 생략하십시오 . “이상한”문자 (줄 바꿈 포함)가 포함 된 파일 이름을 처리합니다.


답변

유닉스와 리눅스의 복도에 조용히 서서주의 깊게 듣는다면, “새줄이 포함 된 파일 이름은 어떻습니까?”라는 귀찮은 목소리가 들립니다.

ls -d *snp* | wc -l

또는, 동등하게 ,

printf "%s\n" *snp* | wc -l

snp개행 문자 가 포함 된 모든 파일 이름을 출력하고 filenames 에 개행 문자
도 포함시킨 다음 출력의 줄 수를 계산합니다. 이름이 파일 인 경우

                                f o o
s n p \n
b a r
. t s v

그 이름은 다음과 같이 쓰여질 것입니다

foosnp
bar.tsv

물론 두 줄로 계산됩니다.

최소한 일부 경우에 더 나은 대안이 몇 가지 있습니다.

printf "%s\n" * | grep -c snp

는를 포함하는 행을 계산 snp하므로 foosnp(\n)bar.tsv위 의 예제는 한 번만 계산합니다. 이것에 대한 약간의 변형은

ls -f | grep -c snp

위의 두 명령은 다음과 같은 점에서 다릅니다.

  • ls -f이름이로 시작하는 파일이 포함됩니다 .; 는 printf … *하지 않는 한,하지 않는 dotglob쉘 옵션이 설정되어 있습니다.
  • printf쉘 내장; ls외부 명령입니다. 따라서 ls약간 더 많은 리소스를 사용할 수 있습니다.
  • 쉘이 a를 처리 할 때 *파일 이름을 정렬합니다.
    ls -f파일 이름을 정렬하지 않습니다. 따라서 ls약간의 리소스를 사용할 수 있습니다.

그러나 그들은 공통점이있다 : 그들은 모두 줄 바꿈을 포함하는 파일 이름의 존재에 잘못된 결과를 줄 것이다 및이 snp이전과 줄 바꿈 후 모두 .

다른:

filenamelist=(*snp*)
echo ${#filenamelist[@]}

그러면을 포함하는 모든 파일 이름을 나열하는 셸 배열 변수가 생성되고 배열 snp의 요소 수가보고됩니다. 파일 이름은 줄이 아닌 문자열로 취급되므로 포함 된 줄 바꿈은 문제가되지 않습니다. 파일 이름 목록이 셸 메모리에 있어야하므로 디렉토리가 크면이 방법에 문제가있을 수 있습니다.

또 다른 :

앞에서 말씀 드렸을 때 printf "%s\n" *snp*, printf명령 "%s\n"은의 확장에서 각 인수에 대해 형식 문자열을 한 번 반복 (재사용)했습니다 *snp*. 여기에 약간의 변화가 있습니다.

printf "%.0s\n" *snp* | wc -l

"%.0s\n"확장의 각 인수에 대해 형식 문자열을 한 번 반복 (재사용)합니다 *snp*. 그러나 "%.0s"각 문자열의 처음 0자를 인쇄한다는 의미입니다. 즉, 아무것도 없습니다. 이 printf명령은 snp이름에 포함 된 각 파일에 대해 줄 바꿈 (즉, 빈 줄) 만 출력합니다 . 그리고 wc -l그들을 계산합니다. 또한 .을 설정 하여 파일을 포함 할 수 있습니다 dotglob.


답변

요약:

“홀수”이름을 가진 파일 (새 줄 포함)에 적용됩니다.

set -- *snp* ; echo "$#"                             # change positional arguments

count=$(printf 'x%.0s' *snp*); echo "${#count}"      # most shells

printf -v count 'x%.0s' *snp*; echo "${#count}"      # bash

기술

간단한 글로브와 함께 모든 파일 이름을 일치로 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

위치 인수를 변경하지 않으려면 각 인수를 한 문자로 변환하고 결과 문자열의 길이를 인쇄하십시오 (대부분의 쉘).

$ printf 'x%.0s' *snp*
xxx

$ count=$(printf 'x%.0s' *snp*); echo "${#count}"
3

또는 bash에서 서브 쉘을 피하려면 다음을 수행하십시오.

$ 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'

따옴표가 없으면 별표가 추가되어 전체 파일 목록으로 확장됩니다.


답변

html 파일 수를 세고 싶다고 가정 해 봅시다.

ls | grep ".html" | wc -l

“snp”의 발생 횟수를 세는 경우 :

ls | grep "snp" | wc -l


답변