我需要使用sed命令(还要使用Linux中的管道)更改文件扩展名,以便可以执行类似mv *.txt *.c
的操作。问题在于我不能使用batch或for循环,所以我必须全部使用管道和sed命令。
您可以使用字符串操作
filename="file.ext1"
mv "${filename}" "${filename/%ext1/ext2}"
如果您的系统支持,您可以使用rename
。
更新
您还可以尝试像这样做:mv ${filename}{ext1,ext2}
这被称为花括号展开
rename
命令...它在大多数 Linux 系统中都可用。 - CS Peised
,我认为你无法重命名文件。 - CS Peifor filename in *.1stextension; do mv "${filename}" "${filename/%1stextension/2ndextension}"; done
这段代码可以用于批量处理文件。不需要使用 sed
。 - bitmask${filename%.ext1}.ext2
POSIX:${filename%.ext1}.ext2
- OJFordfind . -name "*.txt" |
sed -e 's|./||g' |
awk '{print "mv",$1, $1"c"}' |
sed -e "s|\.txtc|\.c|g" > table;
chmod u+x table;
./table
我不知道为什么你不能使用循环语句,使用它可以让生活更加轻松:
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
您可以使用find
查找所有文件,然后将其导入到while read
循环中:
$ find . -name "*.ext1" -print0 | while read -d $'\0' file
do
mv $file "${file%.*}.ext2"
done
${file%.*}
是小的右侧模式过滤器。百分号%
标记要从右侧删除的模式(匹配最小的glob模式),.*
是模式(最后一个.
后面的字符)。
-print0
会使用NUL
字符而不是\n
分隔文件名。-d $'\0'
将读取以NUL
字符分隔的文件名,这样,具有空格、制表符、\n
或其他奇怪字符的文件名将被正确处理。for
时遇到了什么问题,但是由于循环解析参数的方式,for
可能会有些棘手。不幸的是,OP没有提供太多关于他们正在做什么的信息。如果有更多信息,我可以给出更好的答案。 - David W.find
和rename
命令。find . -type f -name "*.ext1" -exec rename -f 's/\.ext1$/ext2/' {} \;
选项 2 使用 find
和 mv
命令
find . -type f -name "*.ext1" -exec sh -c 'mv -f $0 ${0%.ext1}.ext2' {} \;
注意:观察到许多终端不支持rename
rename
无法工作,请尝试使用选项2的 mv
。即使我也不确定为什么许多终端无法使用 rename
。对于我来说,在 ubuntu
中可以工作,但在 RHEL
中不行。 - jkshah使用sed和sh的另一种解决方案
printf "%s\n" *.ext1 |
sed "s/'/'\\\\''/g"';s/\(.*\)'ext1'/mv '\''\1'ext1\'' '\''\1'ext2\''/g' |
sh
perl -le '($e,$f)=@ARGV;map{$o=$_;s/$e$/$f/;rename$o,$_}<*.$e>' ext2 ext3
好的,这应该可以工作。
mv $file $(echo $file | sed -E -e 's/.xml.bak.*/.xml/g' | sed -E -e 's/.\///g')
输出
abc.xml.bak.foobar -> abc.xml