저는 Linux를 처음 접했고 디렉터리에 있는 파일과 하위 디렉터리의 모든 이름(인수로 제공됨)을 인쇄하고 각각에 대해 동일한 이름을 가진 파일 수를 인쇄해야 하는 쉘 스크립트를 작성해야 하는 과제를 받았습니다. 이 디렉토리의 파일입니다.
내 문제는 모든 파일과 디렉터리의 이름을 인쇄할 수 있고 작업의 두 번째 부분도 수행할 수 있지만 이를 하나로 합칠 수 없다는 것입니다. 즉, 내 출력에는 두 가지 다른 부분이 있습니다.
/some/path
a1
a2
a3
a1 1
a2 1
#a1, a2 files and a3 directory
다음과 같아야 합니다.
a1 1
a2 1
a3
이것은 쉘 스크립트를 작성하는 데 사용하는 코드입니다.
#the first part that prints all the names from the directory
mydir=$1
cd $mydir
ls -l $mydir | awk '{print $9}'
#the second part that prints the number of files with the same name for every file
file=$(find $mydir -type f -printf '%f\n' | sort | uniq -c)
echo $file
답변1
"Linux/Shell 스크립팅 학습" 과제의 맥락에서 다음을 제안합니다.
mydir=$1
for f in "$mydir"/*
do
printf "%s %d\n" "$f" $(find "$mydir" -name "$f" -print 2>/dev/null | wc -l)
done
스크립트 조정:
cd
디렉토리를 입력ls
할 필요가 없습니다.- 파일 이름은 필요하지 않습니다
awk
. 그렇게 할 수는 있지만ls
... - 별도로 실행하면 별도의 출력이
ls ... awk
표시됩니다 .find
find
수행 중인 작업이 출력을 계산하는 것뿐이라면 출력을 특별히 인쇄할 필요가 없습니다.- 당신이 하는 모든 것이 출력을 계산하는 것이라면 출력을 정렬할 필요가 없습니다.
uniq
모든 것을 캡처하려면 사용할 필요가 없습니다.-type f
당신의 과제에서 당신이 그것을 찾을 수 있기를 바라는 경우를 대비하여 나는 그것을 제거하는 자유를 가졌습니다.목차같은 이름-name "$f"
이름이 일치 하는find
파일 만 추가printf
파일 이름과 개수를 동일한 출력 라인에 결합하는 데 사용됩니다.ls
파일 이름을 얻기 위해 출력을 구문 분석할 필요가 없습니다 .for f in "$mydir"/*
즉,*
파일 이름과 일치하도록 확장됩니다.
또한 사용자가 다음과 같은 것을 제공하는 경우를 대비하여 모든 변수 사용법을 인용했습니다 "this file"
.
출력에 숨겨진 파일은 표시되지 않습니다. 도트 파일(숨겨진 파일)과 일치하도록 확장자를 추가할 수도 있습니다 shopt -s dotglob
."$mydir"/*
고급 경고로서, 사용자가 개행 문자가 포함된 파일 이름을 조회에 전달하면 개행 문자가 포함된 파일 이름이 잘못 계산됩니다.