简体   繁体   English

在bash中更改文件扩展名

[英]Changing file extension in bash

Hello i have to change file extension, but i must type it when i call script 您好,我必须更改文件扩展名,但是我在调​​用脚本时必须输入文件扩展名

so i trying 所以我尝试

 #!/bin/bash
echo "Hello "
roz1="$1"
roz2="$2"
katalog="$3" 
for i in `find . -name '*$roz1'`
do 
tmp=`basename $i $roz1t`
mv "${tmp}$roz1" "${tmp}$roz2"
done 

And i type /.script .txt .html When i change it to this 当我将其更改为/.script .txt .html时,

#!/bin/bash
echo "Hello "
roz1="$1"
roz2="$2"
katalog="$3" 
for i in `find . -name '*.txt'`
do 
tmp=`basename $i .txt`
mv "${tmp}.txt" "${tmp}.html"
done

All working file, i known it is bad variables $1 $2 call , but i can't fix it. 所有工作文件,我都知道它是错误的变量$ 1 $ 2 call,但我无法修复它。

There are several quick and easy ways to approach this problem. 有几种快速简便的方法可以解决此问题。 Following from your attempt, we take the current and new extensions from the command line. 根据您的尝试,我们从命令行获取当前和新的扩展名。 You then need to validate 2 inputs and then remove the leading '.' 然后,您需要验证2个输入,然后删除前导'.' if any from the front of each extension in order to be able to consistently handle user input with or without a leading dot. (如果有的话)位于每个扩展名的前面,以便能够始终如一地处理带有或不带有前导点的用户输入。

Then it is a simple matter of selecting the files by extension, and move while removing the unwanted extension and appending the new one. 然后,只需按扩展名选择文件,然后在删除不需要的扩展名并附加新扩展名的同时移动即可。 That can take place all in one call using substring extraction: 这可以使用子字符串提取在一个调用中全部完成:

#!/bin/bash

[ -z $1 -o -z $2 ] && {  ## validate both extensions given
    printf "error: insufficient input. usage: %s ext1 ext2\n" "${0//*\//}"
    exit 1
}

ext1="$1"  ## assign input to variables
ext2="$2"

## remove leading '.' if it exists
#  allows handling with/without '.'
[ ${ext1:0:1} = . ] && ext1=${ext1:1}
[ ${ext2:0:1} = . ] && ext2=${ext2:1}

## read each file in list
while read -r fname; do

    ## simple move from ext1 to ext2 using substring extraction
    mv "$fname" "${fname%.$ext1}.$ext2"

done < <(find . -type f -name "*.$ext1")

exit 0

Explanation 说明

${var#expression} or ${var%expression} relies on parameter expansion/substring removal . ${var#expression}${var%expression}依赖于参数扩展/子字符串移除 Those are the two basic forms. 这是两种基本形式。 The first with # says remove the first occurrence of what is in expression from $var starting from the LEFT . 第一个带有# expressionLEFT开始从$var删除expression 第一次出现的内容。 The % variant starts from the RIGHT . %变体从RIGHT开始。 Using ## or %% says remove all occurrences of expression in $var . 使用##%%表示删除$var所有出现的表达式。 So "${fname%.$ext1}.$ext2" says remove the contents of $ext1 (the first extension) from the full filename $fname (from the right -- leaving only the filename without an extension) and then tack .$ext2 (the new extension) on to the end (creating your new file name). 因此, "${fname%.$ext1}.$ext2"表示从完整文件名$fname (从右起-仅保留文件名不带扩展名)中删除$ext1 (第一个扩展名)的内容,然后添加.$ext2 (新扩展名)结尾(创建新文件名)。 Example: 例:

$ a=file.txt; echo ${a%.txt}; echo ${a%.txt}.html
file
file.html

The ${ext1:0:1} type are simple string index expressions. ${ext1:0:1}类型是简单的字符串索引表达式。 They are ${var:start:length} (where if no length , the default is from start to end of string ). 它们是${var:start:length} (如果没有length ,则默认为从string的开始到结尾 )。 So ext1=${ext1:1} just says skip the 1st char and copy remainder. 因此ext1=${ext1:1}只是说跳过第一个字符并复制剩余的字符 (basically drop the first char if it was a '.' ). (如果是'.'则基本上删除第一个字符)。 You can also index from the end, but the syntax is special. 您也可以从头开始索引,但是语法很特殊。 To index from the end, you use ${var: -4:1} ( note the space between : -4 ) or you can use parenthesis ${var:(-4):1} . 要从末尾开始索引,请使用${var: -4:1}请注意: -4之间的空格 ),也可以使用括号${var:(-4):1} Both start 4 chars from the end and get 1 char (eg the . in file.txt ). 两者都从末尾开始4个字符,并得到1个字符(例如, file.txt. )。 Example: 例:

$ a=file.txt; b=file.txt; echo ${a: -4:1}; echo ${b:(-4):1}
.
.

Test Files for the full script 完整脚本的测试文件

$  ls -1
chext.sh
file1.txt
file2.txt
file3.txt
file4.txt
file5.txt

Use/Result 使用/结果

Changing .txt extensions to .html: 将.txt扩展名更改为.html:

$ bash chext.sh txt html

$ ls -1
chext.sh
file1.html
file2.html
file3.html
file4.html
file5.html

You should read about Quoting . 您应该阅读有关报价的信息
find . -name '*$roz1' find . -name '*$roz1' will actually match literal $roz1, it will not be expanded. find . -name '*$roz1'实际上将与文字$ roz1匹配,因此不会扩展。

You should use double quotes like find . -name "*$roz" 您应该使用双引号,如find . -name "*$roz" find . -name "*$roz"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM