2013-10-03 146 views
2

我必須做一個sed行(在Linux中也使用管道)來更改文件擴展名,所以我可以做一些mv *.1stextension *.2ndextension類似mv *.txt *.c。問題是我不能使用批處理或for循環,所以我必須使用pipes和sed命令完成所有操作。如何使用sed更改文件擴展名?

+0

您可以用'xargs'? – Floris

+2

爲什麼你不能使用循環?你應該說清楚!你做這個作爲功課的一部分嗎? – iamauser

+0

當然我是,我沒有提到,但我認爲這是相當知名的,因爲有限制 – antonbalboa

回答

9

你可以使用字符串操作

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

或者,如果你的系統支持,您可以使用rename

更新

你也可以做這樣的

mv ${filename}{ext1,ext2} 

被稱爲括號擴展

+0

這是如何工作的大量文件? – Floris

+0

我不知道我們是否被允許用戶'重命名'...它是在大多數Linux系統中可用 –

+0

謝謝,但我不能使用任何批處理或腳本語句,我只能使用我的命令行,sed和管道 – antonbalboa

1

的東西,這可能工作:

find . -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 
+0

OP說沒有'for'循環... –

+0

aha!沒有看到... – iamauser

+0

我不應該使用任何循環或句子,只是管道,命令行和sed – antonbalboa

2

您可以使用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或其他古怪字符的文件名將被正確處理。

+0

這是怎麼回事不是循環? OP不想要任何循環! – iamauser

+0

這是一根管子。正如OP所言:「我必須用**管道和sed command_完成所有工作。」我不確定OP對''for'有什麼問題,但'for'會因爲它分析循環參數的方式而造成麻煩。不幸的是,OP沒有提供他們正在做什麼的很多信息。有了更多的信息,我可以給出更好的答案。 –

+0

同意你,OP沒有提供足夠的信息,爲什麼不循環! – iamauser

2

您可以嘗試以下選項

選項1find隨着rename

find . -type f -name "*.ext1" -exec rename -f 's/\.ext1$/ext2/' {} \; 

選項2find隨着mv

find . -type f -name "*.ext1" -exec sh -c 'mv -f $0 ${0%.ext1}.ext2' {} \; 

注意:據觀察,rename不適用於許多終端

+0

不適用於我...它不會改變 – iamauser

+0

@iamauser如果'rename'不起作用,請嘗試使用選項2'mv'。即使我不確定爲什麼「重命名」不適用於許多終端。對我來說,它可以在'ubuntu'中使用,但不能在'RHEL'中使用。 – jkshah

5

sed用於操作文件的內容,而不是文件名本身。我的建議:

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

或者,有這existing question這應該有所幫助。

+0

我不得不在Makefile中用.o替換.o .o。這解決了我的問題,謝謝。 – Garini

2

另一種解決方案只有SED和SH

printf "%s\n" *.ext1 | 
sed "s/'/'\\\\''/g"';s/\(.*\)'ext1'/mv '\''\1'ext1\'' '\''\1'ext2\''/g' | 
sh 

有更好的表現:只有一個進程創建

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