bash检查目录中所有文件的扩展名

bash检查目录中所有文件的扩展名,bash,shell,ubuntu,Bash,Shell,Ubuntu,我正在编写一个shell脚本,通过用户输入读取给定目录中的所有文件,然后计算有多少文件具有该扩展名。我刚开始学习Bash,我不知道为什么它没有定位文件或读取目录。我只举了2个例子,但我的计数总是0 这就是我运行脚本的方式 $./check_ext.sh /home/user/temp 我的脚本检查_ext.sh #!/bin/bash count1=0 count2=0 for file in "ls $1" do if [[ $file == *.sh ]]; then ech

我正在编写一个shell脚本,通过用户输入读取给定目录中的所有文件,然后计算有多少文件具有该扩展名。我刚开始学习Bash,我不知道为什么它没有定位文件或读取目录。我只举了2个例子,但我的计数总是0

这就是我运行脚本的方式

$./check_ext.sh /home/user/temp
我的脚本检查_ext.sh

#!/bin/bash

count1=0
count2=0

for file in "ls $1"
do
if [[ $file == *.sh ]]; then 
    echo "is a txt file"
    (( count1++ ))
elif [[ $file == *.mp3 ]]; then
    echo "is a mp3 file"
    (( count2++ ))
fi  
done;

echo $count $count2
“ls$1”
不会在
$1
上执行
ls
,它只是一个普通字符串。命令替换语法为
$(ls“$1”)

但是,不需要使用
ls
,只需使用globbing即可:

count1=0
count2=0

for file in "$1"/*; do
   if [[ $file == *.sh ]]; then 
       echo "is a txt file"
       (( count1++ ))
   elif [[ $file == *.mp3 ]]; then
       echo "is a mp3 file"
       (( count2++ ))
   fi  
done

echo "counts: $count1 $count2"
“$1”/*中文件的
将遍历由
$1
表示的目录中的所有文件/目录


编辑:用于在目录中递归执行此操作:

count1=0
count2=0

while IFS= read -r -d '' file; do
   if [[ $file == *.sh ]]; then 
       echo "is a txt file"
       (( count1++ ))
   elif [[ $file == *.mp3 ]]; then
       echo "is a mp3 file"
       (( count2++ ))
   fi  
done < <(find "$1" -type f -print0)

echo "counts: $count1 $count2"
count1=0
count2=0
而IFS=read-r-d“”文件;做
如果[[$file==*.sh]];然后
echo“是一个txt文件”
((count1++)
elif[[$file==*.mp3]];然后
echo“是一个mp3文件”
((count2++)
fi
正确完成<

count1=0
count2=0

for f in "$1"/*; do
  case $f in
     (*.sh) printf '%s is a txt file\n' "$f"; : "$((count1+=1))" ;;
    (*.mp3) printf '%s is a mp3 file\n' "$f"; : "$((count2+=1))" ;;
  esac
done

printf 'counts: %d %d\n' "$count1" "$count2"

您也可以为此使用Bash数组:如果您只想处理扩展名
sh
mp3

#!/bin/bash

shopt -s nullglob

shs=( "$1"/*.sh )
mp3s=( "$1"/*.mp3 )

printf 'counts: %d %d\n' "${#shs[@]}" "${#mp3s[@]}"
如果您想处理更多扩展,可以概括此过程:

#!/bin/bash

shopt -s nullglob

exts=( .sh .mp3 .gz .txt )
counts=()

for ext in "${exts[@]}"; do
    files=( "$1"/*."$ext" )
    counts+=( "${#files[@]}" )
done

printf 'counts:'
printf ' %d' "${counts[@]}"
echo
如果要处理所有扩展(使用关联数组,在Bash中提供≥(四)


如果您只是想解决一个问题
find
可以帮您解决。如果您想学习bash编程,请按“好先生”。非常感谢。是否可以读取其子文件夹?例如,如果“/home/user/temp/sub/sub”中有文件,只需对“$1”/*“$1”sub/*中的文件运行如下循环:
;执行
但是如果您想要所有子文件夹,那么我建议使用
查找
抱歉,我更改了代码“FILES=$(find$1)for file in$FILES)”,但没有循环for循环。是否将目录作为整个文本块而不是单个文件读取
#!/bin/bash

shopt -s nullglob

declare -A exts

for file in "$1"/*.*; do
    ext=${file##*.}
    ((++'exts[$ext]'))
done

for ext in "${!exts[@]}"; do
    printf '%s: %d\n' "$ext" "${exts[$ext]}"
done