Contents

如何检查目录中是否存在文件类型

1. 概述

在某些情况下,我们想检查某个文件类型是否存在于目录中。例如,我们可能想查看目录中是否有 PNG 图像。这样,我们可以收集指定存储位置的所有 PNG 文件。

在本教程中,我们将讨论检查目录中文件类型的各种方法。

2. 示例目录

本教程中的示例使用名为directory的目录,该目录具有以下内容:

$ ls -1 directory/
handlers.py
hello2.sh
hello-world.sh
images
project_source_code.zip
python_code.py
ReactART.js

3. 使用ls检查文件类型

我们经常通过查看文件的扩展名来确定文件类型。使用这种方法,我们可以使用** ls命令列出具有特定文件类型的所有文件**:

$ ls directory/*zip
directory/project_source_code.zip

但我们都知道,一个文件可以隐藏一个虚假的扩展名。例如,ZIP 文件可以具有*.txt*扩展名:

$ mv directory/project_source_code.zip directory/project_source_code.txt
$ ls directory/*txt
directory/project_source_code.txt

但是,根据扩展名检查文件类型是一种合理的方法。稍后,我们将讨论一种基于文件内容而不是扩展名来检查文件类型的方法。

如果我们要检查目录文件类型怎么办?目录通常没有扩展名。我们可以在参数中使用*-d*标志和*/:

$ ls -d directory/*/
directory/images/  directory/python_code.py/

-d标志仅列出目录,参数中的*/表示所有以斜线*/*结尾的内容。

4. 使用find检查文件类型

我们可以使用find 命令根据条件查找文件。此命令可以通过-name*选项根据文件的扩展名过滤文件*:

$ find directory -name "*.js"
directory/ReactART.js

请注意,由于星号,我们必须将模式放在双引号中。这种模式意味着所有以*.js*结尾的东西。

我们还可以使用*-type*选项过滤目录:

$ find directory/* -type d
directory/images
directory/python_code.py

5. 用file检查文件类型

file命令将根据文件的内容检查文件的文件类型

$ file directory/handlers.py 
directory/handlers.py: Python script, ASCII text executable

我们可以给这个 Python 脚本一个虚假的扩展名,但是file命令可以看穿它:

$ mv directory/handlers.py directory/handlers.zip
$ file directory/handlers.zip
directory/handlers.zip: Python script, ASCII text executable

file命令可以接受多个参数和一个模式:

$ file directory/handlers.py directory/hello-world.sh 
directory/handlers.py:    Python script, ASCII text executable
directory/hello-world.sh: Bourne-Again shell script, ASCII text executable
$ file directory/*py
directory/handlers.py:    Python script, ASCII text executable
directory/python_code.py: directory

但是,file命令并不完美。有时,它无法猜测正确的文件类型

$ head directory/ReactART.js
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import * as React from 'react';
import ReactVersion from 'shared/ReactVersion';
import {LegacyRoot} from 'react-reconciler/src/ReactRootTags';
$ file directory/ReactART.js 
directory/ReactART.js: C++ source, ASCII text

file命令无法猜测ReactART.js的文件类型。它应该是 JavaScript 源代码,而不是 C++ 源代码。

要使用file命令过滤文件,我们可以将其与awk 命令和grep 命令结合使用。假设我们有一堆文件,我们想检查是否有 Python 脚本。我们可以使用awkgrep命令拆分file命令的输出:

$ file directory/* | awk -F':' '{print $2}' | awk '{$1=$1};1'
directory
Python script, ASCII text executable
Bourne-Again shell script, ASCII text executable
Bourne-Again shell script, ASCII text executable
directory
Zip archive data, at least v1.0 to extract
directory
C++ source, ASCII text
$ file directory/* | awk -F':' '{print $2}' | awk '{$1=$1};1' | grep "Python script"
Python script, ASCII text executable

-F标志是选择分隔符。带花括号的字符串中的*$2是分隔输出字符串的第二列。最后一个awk*命令是修剪输出的前导空格。

当然,我们不必使用awk命令:

$ file directory/* | grep "Python script"
directory/handlers.py:             Python script, ASCII text executable

我们只需要确保文件名中没有包含“Python 脚本”的文件。

6. 使用 Bash 脚本检查文件类型

Bash 支持检查目录中的文件类型。我们可以在if语句中使用-e-d和*-f*标志**:

$ cat check-file-type.sh
#!/bin/bash
if [ -e directory/*.js ]; then
  echo "There are JavaScript files or directories with .js extension inside 'directory'"
fi
if [ -d directory/ ]; then
  echo "'directory' is a directory"
fi
if [ -f directory/*.js ]; then
  echo "There are JavaScript files (not directories with .js extension) inside ‘directory’"
fi
$ ./check-file-type.sh
There are JavaScript files or directories with .js extension inside 'directory'
'directory' is a directory
There are JavaScript files (not directories with .js extension) inside 'directory'

-e标志是检查文件或目录是否存在。-f标志是检查普通文件(不是目录)是否存在。最后,-d标志是检查这是否是一个目录。此标志不能接受通配符参数。