bash 如何使用 sed 更改文件扩展名?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19164976/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 08:10:13  来源:igfitidea点击:

How to use sed to change file extensions?

linuxbashsed

提问by heythatsmekri

I have to do a sed line (also using pipes in Linux) to change a file extension, so I can do some kind of mv *.1stextension *.2ndextensionlike mv *.txt *.c. The thing is that I can't use batch or a for loop, so I have to do it all with pipes and sed command.

我必须做一个 sed 行(也在 Linux 中使用管道)来更改文件扩展名,所以我可以做一些mv *.1stextension *.2ndextension类似mv *.txt *.c. 问题是我不能使用批处理或 for 循环,所以我必须使用管道和 sed 命令来完成这一切。

回答by CS Pei

you can use string manipulation

你可以使用字符串操作

filename="file.ext1"
mv "${filename}" "${filename/%ext1/ext2}"

Or if your system support, you can use rename.

或者,如果您的系统支持,您可以使用rename.

Update

更新

you can also do something like this

你也可以做这样的事情

mv ${filename}{ext1,ext2}

which is called brace expansion

这称为大括号扩展

回答by chooban

sed is for manipulating the contents of files, not the filename itself. My suggestion:

sed 用于操作文件的内容,而不是文件名本身。我的建议:

rename 's/\.ext/\.newext/' ./*.ext

Or, there's this existing questionwhich should help.

或者,这个现有的问题应该会有所帮助。

回答by iamauser

This may work:

这可能有效:

find . -name "*.txt" | 
sed -e 's|./||g' | 
awk '{print "mv",, "c"}' | 
sed -e "s|\.txtc|\.c|g" > table;
chmod u+x table;
./table

I don't know why you can't use a loop. It makes life much easier :

我不知道你为什么不能使用循环。它让生活更轻松:

newex="c";  # Give your new extension
for file in *.*;  # You can replace with *.txt instead of *.*
do 
 ex="${file##*.}";    # This retrieves the file extension
 ne=$(echo "$file" | sed -e "s|$ex|$newex|g"); # Replaces current with the new one
 echo "$ex";echo "$ne";
 mv "$file" "$ne";
done

回答by David W.

You can use findto find all of the files and then pipe that into a while readloop:

您可以使用find来查找所有文件,然后将其通过管道传输到while read循环中:

$ find . -name "*.ext1" -print0 | while read -d $'
find . -type f -name "*.ext1" -exec rename -f 's/\.ext1$/ext2/' {} \;
' file do mv $file "${file%.*}.ext2" done

The ${file%.*}is the small right pattern filter. The %marks the pattern to remove from the right side (matching the smallest glob pattern possible), The .*is the pattern (the last .followed by the characters after the .).

${file%.*}小权模式筛选。The%标记要从右侧移除的模式(匹配可能的最小 glob 模式), The.*是模式(最后一个.跟在 之后的字符.)。

The -print0will separate file names with the NULcharacter instead of \n. The -d $'\0'will read in file names separated by the NULcharacter. This way, file names with spaces, tabs, \n, or other wacky characters will be processed correctly.

-print0将文件名以独立的NUL性格,而不是\n。该-d $'\0'会由分隔的文件名读取NUL字符。这样,带有空格、制表符\n、 或其他古怪字符的文件名将被正确处理。

回答by jkshah

You may try following options

您可以尝试以下选项

Option 1findalong with rename

选项 1findrename

find . -type f -name "*.ext1" -exec sh -c 'mv -f 
printf "%s\n" *.ext1 | 
sed "s/'/'\\''/g"';s/\(.*\)'ext1'/mv '\'''ext1\'' '\'''ext2\''/g' | 
sh
${0%.ext1}.ext2' {} \;

Option 2findalong with mv

选项 2find连同mv

perl -le '($e,$f)=@ARGV;map{$o=$_;s/$e$/$f/;rename$o,$_}<*.$e>' ext2 ext3

Note: It is observed that renamedoesn't work for many terminals

注意:据观察,这rename不适用于许多终端

回答by Nahuel Fouilleul

Another solution only with sed and sh

仅使用 sed 和 sh 的另一种解决方案

##代码##

for better performance: only one process created

为了更好的性能:只创建一个进程

##代码##