![폴더에 확장자를 가진 파일이 포함되어 있는지 확인하고 디렉터리를 범주에 기록합니다.](https://rvso.com/image/1684200/%ED%8F%B4%EB%8D%94%EC%97%90%20%ED%99%95%EC%9E%A5%EC%9E%90%EB%A5%BC%20%EA%B0%80%EC%A7%84%20%ED%8C%8C%EC%9D%BC%EC%9D%B4%20%ED%8F%AC%ED%95%A8%EB%90%98%EC%96%B4%20%EC%9E%88%EB%8A%94%EC%A7%80%20%ED%99%95%EC%9D%B8%ED%95%98%EA%B3%A0%20%EB%94%94%EB%A0%89%ED%84%B0%EB%A6%AC%EB%A5%BC%20%EB%B2%94%EC%A3%BC%EC%97%90%20%EA%B8%B0%EB%A1%9D%ED%95%A9%EB%8B%88%EB%8B%A4..png)
약 3,000개 이상의 폴더가 있고 여기에는 단일 스프링 파일과 한 쌍의 fastq.gz 파일이라는 두 가지 유형의 파일이 있을 수 있습니다. 폴더를 스캔하고 파일 확장자 중 하나 또는 둘 모두가 디렉터리에 있는지 알고 싶습니다.
- fastq.gz 및 spring 파일 쌍을 포함합니다.
- fastq.gz 파일 1개와 스프링 파일 1개
- 단일 스프링 파일
- fastq.gz 파일 쌍
- 단일 fastq.gz 파일
사용했지만 오류가 [ /path/to/dir/*fastq.gz ]
발생 unary operator expected
하고 사용이 [[ ]]
올바르게 테스트되지 않는 것 같습니다.
내가 사용한 실제 스크립트는 -
check_dir () {
in="$1"
echo "$in Checking for spring"
[ "$in"/*spring -f ] && echo "$in"
}
export -f check_dir
저는 bash를 사용하고 있습니다. 논리에 대한 도움을 주시면 감사하겠습니다.
답변1
unary operator expected
[
은 *
(는) 독립적으로 작동하기 때문입니다 *fastq.gz
.
[
쉘 구문이 아닙니다. [
일반 명령(Bash에 내장되어 있지만 여전히 명령임)이며 ]
마지막 명령입니다.논쟁, 필수 항목입니다. 그 사이의 모든 것도 논쟁입니다.
쉘은 /path/to/dir/*fastq.gz
호출하기 전에 하나 이상의 단어로 확장됩니다 [
. [
이 단어와 필수 단어를 ]
인수로 볼 것입니다. 인수 수와 인수에 따라 [
0개 이상의 인수가 연산자(예: -f
)가 될 것으로 예상됩니다.
단일 인수로 확장되면 유효 [ /path/to/dir/*fastq.gz ]
합니다 /path/to/dir/*fastq.gz
("유효할 것입니다"는 "원하는 것을 수행할 것입니다"와 동일하지 않음). 여기에는 일치하는 항목이 없는 경우도 포함됩니다 *
. 전통적으로(Bash에서는 기본적으로) 일치하는 항목이 없으면 /path/to/dir/*fastq.gz
있는 그대로 처리됩니다. 여러 단어로 확장 될 수 있으며 /path/to/dir/*fastq.gz
그 중 어느 것도 운영자가 이해하는 것처럼 보이지 않습니다 [
. 발생한 오류는 패턴이 두 단어로 확장된 경우에 발생했을 가능성이 높습니다.
나중에 [ "$in"/*spring -f ]
. 이것은 훨씬 더 나쁩니다. 아마도 당신이 [ -f some/path ]
어디에 -f
있는지 같은 것을 원했기 때문입니다.~ 전에테스트할 경로입니다. 여전히 [ -f "$in"/*spring ]
강력한 수정 사항은 아닙니다."$in"/*spring
일반적으로여러 가지 주장으로 확장될 수 있으며 [
이를 견디지 못할 수 있습니다. 디렉터리당 최대 하나의 파일이 있다고 썼 *spring
으므로당신의 경우에는이와 같은 코드는 어느 정도 작동할 수 있습니다. 그래도 여전히 열악한 코드입니다.
에서는 여러 단어로 확장될 수 있는 [
와일드카드를 사용하지 마십시오 . *
이는 즉시 또는 곧 실패합니다.[[
후드 아래는 다릅니다하지만 그것은 당신의 목적에도 좋지 않습니다.
패턴과 일치하는 파일 수를 알고 싶습니다 /path/to/dir/*fastq.gz
. 이를 수행하는 올바른 방법은 확장 결과를 배열에 할당하는 것입니다. 이식 가능한 배열은 하나뿐입니다. 즉, 쉘 스크립트(또는 쉘 함수)의 인수 배열입니다. 일치 항목이 0인 경우를 감지하려면 추가 코드가 필요합니다(이 경우에도 확장되지 않은 패턴 문자열이라는 하나의 단어가 생성됩니다). 귀하의 질문에 태그가 지정되었습니다.세게 때리다, 따라서 명명된 배열과 기타 이식 불가능한 기능을 사용할 것입니다.
# non-portable code, works in Bash
check_dir () (
dir="${1-.}"
dir="${dir%/}/"
[ -d "$dir" ] || { echo "Not a directory." >&2; return 1; }
shopt -s nullglob
files=( "$dir"/*fastq.gz )
nf="${#files[@]}"
files=( "$dir"/*spring )
ns="${#files[@]}"
printf '%s\t%s\t%s\n' "$nf" "$ns" "$dir"
)
사용법: check_dir path/to/dir
또는 check_dir
(기본 경로는 .
). 이 함수는 파일 수 *fastq.gz
, 탭, 파일 수 *spring
, 탭, 마지막으로 검사된 경로(뒤에 로 인쇄됨 /
)를 인쇄합니다.
이제 디렉토리 트리를 분석할 수 있습니다(아래 함수를 사용하려면 위 함수를 정의해야 합니다).
# non-portable code, works in Bash
check_dirs () (
dir="${1-.}"
dir="${dir%/}/"
[ -d "$dir" ] || { echo "Not a directory." >&2; return 1; }
shopt -s nullglob globstar
for d in "$dir"**/; do
check_dir "$d"
done
)
사용법: check_dirs path/to/dir
또는 check_dirs
(기본 경로는 .
).
노트:
큰 디렉토리 트리의 경우
check_dirs
처음에는 정지된 것처럼 보일 수 있습니다. 이는 호출되어 무엇이든 인쇄하기for d in "$dir"**/
전에 완전히 확장되어야 하기 때문입니다.check_dir
함수는 의도적으로 하위 쉘(
check_dir () (
과 반대check_dir () {
)로 정의되므로 쉘 옵션(shopt
)과 모든 변수는 로컬입니다.숨겨진 파일 수를 계산 하려면 이 기능이
check_dir
필요합니다dotglob
(예shopt -s nullglob dotglob
: ).숨겨진 디렉토리로 내려 가려면 이 기능이
check_dirs
필요합니다dotglob
(예shopt -s nullglob globstar dotglob
: ).디렉터리 이름에 개행 문자가 포함되어 있지 않으면 표준 도구를 사용하여
check_dir
또는 의 출력을 쉽게 구문 분석할 수 있습니다.check_dirs
유용한 명령:sort -n
,grep $'^2\t1\t'
,cut -f 3-
../
예를 들어 정확히 하나의*fastq.gz
파일과 정확히 0개의 파일이 있는 디렉터리를 찾으려면 다음을 수행합니다*spring
.check_dirs | grep $'^1\t0\t' | cut -f 3-