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
How to use sed to change file extensions?
提问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 *.2ndextension
like 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 find
to find all of the files and then pipe that into a while read
loop:
您可以使用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 -print0
will separate file names with the NUL
character instead of \n
. The -d $'\0'
will read in file names separated by the NUL
character. 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 1find
along with rename
选项 1find
与rename
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 2find
along with mv
选项 2find
连同mv
perl -le '($e,$f)=@ARGV;map{$o=$_;s/$e$/$f/;rename$o,$_}<*.$e>' ext2 ext3
Note: It is observed that rename
doesn'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
为了更好的性能:只创建一个进程
##代码##