폴더 내부의 요소 수를 계산하고 싶습니다. 나는 그것에 대해 생각했다
function lsc { /bin/ls -l $1 | sed 1d | wc -l }
그러나 나는 사람들이 어떻게 이 파이프들을 줄이고 여분의 것들을 awk
제거하고 있는지 기억해냈습니다 . 그래서 당신은 무엇을 합니까 ?grep
sed
awk
답변1
ls
, sed
또는 wc
가 필요하지 않습니다 awk
.
패턴이 확장되는 이름의 수를 세고 싶다면 다음을 사용할 수 있습니다.
set -- *
echo "$#"
이 set
명령은 위치 인수( 등)를 패턴 과 일치하는 이름 $1
으로 설정합니다 . 이는 자동으로 특수 변수를 설정된 위치 인수 수, 즉 주어진 패턴과 일치하는 이름 수로 설정합니다.$2
*
$#
bash
명명된 배열이 있는 셸 에서는 다음을 사용할 수 있습니다.
names=(*)
echo "${#names[@]}"
이는 유사하게 작동하지만 배열의 요소를 names
패턴 확장에 의해 생성된 이름으로 설정합니다 *
. 변수 확장은 ${#names[@]}
배열의 요소 수입니다 names
.
이에 대한 한 가지 문제는 패턴이 아무것도 일치하지 않으면 확장되지 않은 상태로 유지되므로 개수가 1이라는 것입니다(디렉토리가 비어 있는 경우에도). 쉘에서 이 문제를 해결하려면 bash
로 nullglob
쉘 옵션을 설정하십시오 shopt -s nullglob
. 이 쉘 옵션을 설정하면 어떤 것과도 일치하지 않는 패턴이 완전히 제거됩니다.
에서 bash
숨겨진 이름의 수도 계산하려면 dotglob
으로 쉘 옵션을 설정하십시오 shopt -s dotglob
.
bash
귀하의 기능은 다음 과 같습니다
lsc () (
shopt -s nullglob
set -- "$1"/*
echo "$#"
)
( ... )
nullglob
호출 셸에서 설정 하지 않도록 함수 본문에서 사용하도록 주의하세요 .
또는 다음의 경우 /bin/sh
:
lsc () {
set -- "$1"/*
if [ -e "$1" ] || [ -L "$1" ]; then
echo "$#"
else
echo 0
fi
}
여기의 명령문은 if
첫 번째 위치 인수가 (아무것도 일치하지 않기 때문에) 확장되지 않은 패턴이 아니라 실제 파일의 이름임을 보장합니다. ( -e
"exists")는 우리가 의 숫자를 신뢰하기 위해 참이어야 합니다 $#
. 잘못된 경우 이름이 테스트의 심볼릭 링크를 참조하는지 확인합니다 -L
. 이것이 사실이라면 패턴이 확장되는 첫 번째 것은 "죽은" 심볼릭 링크(존재하지 않는 파일을 가리키는 심볼릭 링크)라는 것을 알고 $#
그것이 정확하다고 믿습니다. 두 테스트가 모두 실패하면 일치하는 항목이 없다는 것을 알 수 있으므로 출력은 입니다 0
.
답변2
첫째, 한 줄짜리 함수 정의가 올바르지 않습니다. 이 키워드가 있다는 것은 아마도 Bash를 사용하고 있음을 나타냅니다. 이것은 function
man bash에 있는 것입니다:Shell Function Definitions
function name [()] compound-command [redirection]
그리고복합 명령로써 정의 된:
{ list; }
따라서 다음과 같아야 합니다.
function lsc { /bin/ls -l $1 | sed 1d | wc -l; }
하지만 기술적으로 정확하더라도 잘 작동하지는 않습니다.
왜아니요구문 분석 ls
(및 수행 방법)?.
다음과 같이 awk를 사용하여 특정 디렉터리에 있는 여러 파일과 디렉터리를 인쇄할 수 있습니다.
awk 'END {print ARGC - 1}' *
그러나 *
awk는 쉘 확장에 대한 인수 중 하나 이상이 디렉토리인 경우 오류를 표시합니다.
$ awk 'END {print ARGC - 1}' *
awk: warning: command line argument `dir1' is a directory: skipped
그러나 어쨌든 결과는 여전히 좋습니다. 오류를 /dev/null로 리디렉션할 수 있습니다.
awk 'END {print ARGC - 1}' * 2>/dev/null