엄청난 양의 파일 목록이 포함된 폴더가 있는데 그 수를 세고 싶습니다. 나는 이것을 하고 있었고 ls -l *.json | wc -l
명령이 더 이상 작동하지 않을 만큼 목록이 충분히 커질 때까지 잘 작동했습니다.
나중에 한 번 시도해 보았는데 ls -l | grep .json | wc -l
정말 효과가 좋았습니다.
그럼 둘의 차이점이 무엇인지 알고 싶습니다. 후자가 ls
모든 파일을 한 번에 처리하지 않고 지속적으로 스트리밍한 grep
다음 wc
? 그렇습니까, 아니면 다르게 작동합니까?
답변1
.json
현재 디렉터리에서 확장명이 있는 숨겨지지 않은 파일의 수를 계산하려면 다음을 수행할 수 있습니다.
(){echo $#} *.json(NoN)
( N
의 경우 nullglob
여기서 oN
필요하지 않은 정렬을 비활성화합니다).
ls -l | grep .json | wc -l
이는 다음과 같은 여러 가지 이유로 잘못된 것입니다.
.
단일 문자와 일치하는 정규식 연산자입니다. 또는 문자열을 검색하려는 경우.json
.grep -F .json
grep '\.json'
grep '[.]json'
- 이는
Xjson
각 행에서 검색됩니다. 를 사용하면ls -l
파일 이름, 사용자 이름, 그룹 이름, 심볼릭 링크 대상 등을 모두 포함할 수 있는 인쇄할 수 있습니다Xjson
. - 파일 이름에는 0과 of
/
(링크 대상에 포함될 수 있음/
)를 제외한 모든 바이트 값이 포함될 수 있습니다. 따라서 이름이xjson\nyjson
심볼릭 링크인 파일이 있으면 파일 은 모두 3줄을 인쇄합니다 . 일부 파일 이름에 현재 로케일 바이트 시퀀스에서 유효한 문자를 형성하지ajson\nbjson
않는 문자가 포함되어 있으면 놀랄 수도 있습니다.-q
ls -l
Xjson
grep | wc -l
일반적으로 로 대체할 수 있습니다grep -c
.
ls -l *.json | wc -l
더 나쁜. 옆에인수 목록이 너무 길면 잠재적인 문제가 발생할 수 있습니다.@L.ScottJohnson도 다음과 같이 지적했습니다.
- 숨겨지지 않은 파일이 없으면 glob을 일치시킬 수 없기 때문에 오류가
.json
발생합니다 .0
zsh
*.json
- 각 매개변수 유형에 대해목차,
ls -l
해당 내용을 나열하므로 디렉토리가 있는 경우dir.json
해당 목록의 모든 행이 계산됩니다. 일반적으로-d
glob 확장을 에 전달할 때 a를 사용 하려고 합니다ls
. .json
파일 이름이 로 시작하는 경우-
해당 파일 이름은 옵션으로 처리됩니다 (특히 옵션이 아닌 인수 이후에도 옵션을 허용하는ls
GNU 또는 비지박스 구현 ).ls
- 위에서 언급한 것처럼 파일 이름이나 기호 링크 대상에 개행 문자가 포함되어 있으면 문제가 발생합니다.
다음 방법을 사용하여 대부분의 문제를 해결할 수 있습니다.
LC_ALL=C ls -qd -- *.json | wc -l
그러나 실제 작업은 모두 쉘에서 수행됩니다. shell은 *.json
파일 목록과 일치하여 에 전달하는 확장입니다 ls
. ls
입력을 위해 각 파일을 별도의 줄에 인쇄하여 wc
계산할 수 있습니다. 또한 존재 여부를 확인하기 위해 각각에 시스템 호출을 하는 ls
것과 같은 불필요한 작업을 많이 수행하고 ( 사용자/그룹 이름 확인을 위해 a 및 일부 uid/gid를 수행하고 심볼릭 링크를 위해 s를 사용) 목록이 정렬됩니다( 쉘은 이미 확장자를 정렬합니다).stat()
-l
lstat()
readlink()
*.json
쉘은 이 확장을 자체적으로 잘 계산합니다.
의 경우 (){echo $#} *.json(NoN)
익명 함수를 사용하며 임시 배열을 사용할 수도 있습니다 files=(*.json(NoN)); echo $#files
.
또한읽다ls
목록을 작성하기 위해 현재 디렉토리의 내용을 사용하므로 이전처럼 각 파일을 개별적으로 찾을 필요가 없습니다 .
이 구문은 구체적입니다 zsh
. POSIX의 해당 구문은 sh
다음과 유사합니다.
set -- [*].json *.json
case $1$2 in
('[*].json*.json') shift 2;;
(*) shift;;
esac
echo "$#"
(파일 목록은 "$@"
(정렬)에 있습니다.)
답변2
확장된 파일 목록이 너무 길면 파일 목록을 확장하기 위해 셸을 사용하기 때문에 원래 명령이 실패할 수 있습니다.
ls -l | grep .json | wc -l
문제 없습니다. 명령줄은 짧고(확장 없음) grep은 한 줄씩 필터링하기 때문입니다.
점은 점뿐만 아니라 모든 문자와 일치합니다. 고정 문자열에는 -F를 사용하십시오.
ls -l | grep -F .json | wc -l
xjson
이렇게 하면 실수로 파일을 일치시키 거나 그와 같은 어리석은 일이 발생하지 않습니다 .
명령에 대한 몇 가지 주의 사항과 의도한 목표를 달성하기 위한 다른 (보다 강력한) 방법이 여전히 있지만 이러한 문제 외에는 파일 이름 와일드카드(예: 셸 확장자)로 필터링하는 것과 파이프라는 두 명령의 차이점이 있습니다. -to-grep