我想知道是否有任何方便的方法来做到这一点。 基本上我想做的是创建一个 shellscript,它会创建多种文件类型的减记。
例如,输出可能如下所示:
ELF 64-bit LSB executable, x86-64: $amount
ELF 32-bit LSB shared> object, INTEL: $amount
ASCII text: $amount
为了使您的文字看起来有点像这样,您需要:
- 创建需要检查的文件列表
- 获取文件名
- 将它们提供给文件实用程序
- 从输出中剪切特定行
首先,要获取我们要检查的所有文件
find $DIR -type f | ls -1
这将打印以下内容(显然是一个示例,结果因设置为 $DIR 的内容而异
mysript.sh
game.exe
text.txt
通过这个,我们将获得当前目录中所有文件的列表的 STDOUT。 但是现在我不确定如何将这些文件名一个一个地提供给文件实用程序以基本上获得我的输出。
最大的问题是,file util 只能处理 1 个文件,不能处理多个目录等。
所以我唯一能想到的就是这样做
FILE_AMOUNT=`find $PWD -type f | ls -1 | wc -l`
while [ "$i" -lt "$FILE_AMOUNT" ]
do
#code here
$(( i++ ))
PRINT_TYPE=`file $myfile | cut -d":" -f2`
done
但我不确定如何一个一个地获取文件并将它们分配给 myfile 变量,以便我们可以循环遍历它们。如您所见,上面的命令转储了多个文件名及其扩展名,但是我不确定如何将它们一个一个地取出并将它们分配给我的文件变量。有什么想法吗?
或者也许有更好的解决方案?
最佳答案
file
命令不从标准输入读取。因此,我们需要遍历文件,对每个文件调用 file
,并将摘要收集到关联数组中:
#!/bin/bash
declare -A file_types
while read -r file; do
type=$(file -b "$file") # -b tells file not to prefix the file name in output
((file_types[$type]++))
done < <(find "$PWD" -type f)
# traverse the associative array and print results
for type in "${!file_types[@]}"; do
printf '%s: %s\n' "$type" "${file_types[$type]}"
done
第一个循环可以更有效地编写,而不需要在子 shell 中调用 file
,如:
while read -r type; do
((file_types[$type]++))
done < <(find "$PWD" -type f -print0 | xargs -0 file -b)
对于我的目录,它给出:
VAX COFF executable - version 5424: 1
VAX COFF executable - version 10614: 1
VAX COFF executable not stripped: 5
VAX COFF executable not stripped - version 902: 1
Perl5 module source text, ASCII text: 7
VAX COFF executable: 3
ASCII text: 23
Perl POD document text, UTF-8 Unicode text: 1
empty: 2
Bourne-Again shell script text executable, ASCII text: 2
VAX COFF executable - version 67: 1
a /usr/bin/env ruby script text executable, ASCII text: 1
POSIX shell script text executable, ASCII text: 12
Git index, version 2, 3 entries: 1
a /usr/bin/perl -w script text executable, ASCII text: 12
ASCII text, with very long lines: 2
Vim swap file, version 7.4: 1
关于bash - 如何递归地按类型获取文件数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42881572/