ubuntu 如何删除目录中特定文件的扩展名?

6xfqseft  于 2023-01-25  发布在  其他
关注(0)|答案(3)|浏览(307)

我想删除具有给定扩展名的特定文件的扩展名。
例如,在目录foobar中,我们有foo.txt, bar.txt foobar.jpg
另外,我放入要删除的扩展名是txt
调用该程序后,输出应为foo bar foobar.jpg
下面是我的代码:

#!/bin/bash
echo "Enter an extension"
read extension
echo "Enter a directory"
read directory
for file in "$directory"/*; do      //
        if [[ $file == *.txt ]]
        then
                echo "${file%.*}"
        else
                echo "$file"

        fi

done

但是,当我在给定目录上运行此命令时,什么也没有显示。
我假设我引用目录的方式有问题(在我放置//的行中),我试图研究如何解决这个问题,但无济于事。
我哪里做错了?

bqucvtff

bqucvtff1#

如果文件确实存在于你输入的***有效的***目录中,那么它们应该会显示出来--只有一个例外。如果你使用的是~/(简写的主目录),那么它在你的for循环中会被当作纯文本处理。read变量应该被替换成另一个变量,这样for loop就可以把它当作一个目录(绝对路径也应该正常工作)。

#!/bin/bash

echo "Enter an extension"
read -r extension
echo "Enter a directory"
read -r directory
dir="${directory/#\~/$HOME}"
for file in "$dir"/*; do
        if [[ $file == *."$extension" ]]
        then
                echo "${file%.*}"
        else
                echo "$file"
        fi
done
7jmck4yq

7jmck4yq2#

您可以简化for循环:

for file in "$directory"/*; do
    echo "${f%.$extension}";
done

%指令只删除匹配的字符。如果没有匹配的字符,则返回原始字符串(此处为f)。

blmhpbnm

blmhpbnm3#

在编写bash脚本时,更常见的是通过命令行参数向脚本传递参数,而不是通过read程序从标准输入中阅读参数。
通过命令行传递参数:

#!/bin/bash

# $# - a bash variable  which holds a number of arguments passed 
# to script via command line arguments

# $0 holds the name of the script

if [[ $# -ne 2 ]]; then # checks if exactly 2 arguments were passed to script
    echo "Usage: $0 EXTENSION DIRECTORY"
    exit -1;
fi

echo $1; # first argument passed to script
echo $2; # second arugment passed to script

这种方法更有效,因为read命令运行时会产生子进程,而阅读命令行参数时不会产生子进程。
没有必要手动循环通过目录,您可以使用find命令来查找给定目录中具有给定扩展名的所有文件。

find /path/to/my/dir -name '*.txt' 

find $DIRECTORY -name "*.$EXTENSION" 
# note that  single quotes in this context would prevent $EXTENSION
#  variable to be resolved, so double quotes are used " "

# find searches for files inside $DIRECTORY and searches for files 
# matching pattern '*.$EXTENSION'

请注意,为了避免bash文件名扩展,有时需要将实际模式用单引号' '或双引号" "括起来。
因此,现在您的脚本可能如下所示:

#!/bin/bash
if [[ $# -ne 2 ]]; then 
    echo "Usage: $0 EXTENSION DIRECTORY"
    exit -1;
fi

$EXTENSION = $1 #  for better readability
$DIRECTORY = $2

for file in `find $DIRECTORY -name "*.$EXTENSION"`; do
   mv $file ${file%.$EXTENSION}
done

构造${file%.$EXTENSION}被称为Shell Parameter Expansion,它在file变量中搜索.$EXTENSION的出现并将其删除。
注意,在脚本中,很容易将扩展名作为目录传递,反之亦然。
我们可以检查第二个参数是否实际上是目录,我们可以使用以下结构:

if ! [[ -d $DIRECTORY ]]; then
    echo $DIRECTORY is not a dir
    exit -1
fi

这样我们就可以更早地退出脚本,并显示更多可读的错误。
总而言之,整个脚本可能如下所示:

#!/bin/bash
if [[ $# -ne 2 ]]; then 
    echo "Usage: $0 EXTENSION DIRECTORY"
    exit -1;
fi

EXTENSION=$1 #  for better readability
DIRECTORY=$2

if ! [[ -d $DIRECTORY ]]; then
    echo $DIRECTORY is not a directory.
    exit -1
fi

for file in `find $DIRECTORY -name "*.$EXTENSION"`; do
   mv $file ${file%.$EXTENSION}
done

示例用法:

$ ./my-script.sh txt /path/to/directory/with/files

相关问题