我有一个包含.zip
文件和其他文件的目录(所有文件有扩展名),我想为所有文件添加后缀没有扩展.zip
名。我能够挑选一个后缀并将其放入变量中$suffix
,因此我尝试了以下代码:
ls -I "*.zip"| xargs -I {} mv {} {}_"$suffix"
这列出了所有没有.zip
且 接近的文件(但错误)。它错误地在 上产生以下结果file.csv
:
file.csv_suffix
我想file_suffix.csv
——如何编辑我的代码以保留文件的扩展名?
答案1
使用起来ls
有点危险。看为什么*不*解析`ls`?
您还必须分开文件名,否则您只需附加$suffix
到它的末尾,正如您发现的那样。
以下是使用find
和不使用 的解决方案find
。
find . -type f ! -name '*.zip' -exec sh -c 'suffix="$1"; shift; for n; do p=${n%.*}; s=${n##*.}; [ ! -e "${p}_$suffix.$s" ] && mv "$n" "${p}_$suffix.$s"; done' sh "$suffix" {} +
这将找到当前目录中或当前目录下某处的所有常规文件,其名称不以.zip
.
然后将使用这些文件的列表调用以下 shell 脚本:
suffix="$1" # the suffix is passed as the first command line argument
shift # shift it off $@
for n; do # loop over the remaining names in $@
p=${n%.*} # get the prefix of the file path up to the last dot
s=${n##*.} # get the extension of the file after the last dot
# rename the file if there's not already a file with that same name
[ ! -e "${p}_$suffix.$s" ] && mv "$n" "${p}_$suffix.$s"
done
测试:
$ touch file{1,2,3}.txt file{a,b,c}.zip
$ ls
file1.txt file2.txt file3.txt filea.zip fileb.zip filec.zip
$ suffix="notZip"
$ find . -type f ! -name '*.zip' -exec sh -c 'suffix="$1"; shift; for n; do p=${n%.*}; s=${n##*.}; [ ! -e "${p}_$suffix.$s" ] && mv "$n" "${p}_$suffix.$s"; done' sh "$suffix" {} +
$ ls
file1_notZip.txt file3_notZip.txt fileb.zip
file2_notZip.txt filea.zip filec.zip
find
如果文件数量不是很大并且不需要递归到子目录(只需稍微修改以跳过非文件名),上面的 shell 脚本就可以独立运行:
#!/bin/sh
suffix="$1" # the suffix is passed as the first command line argument
shift # shift it off $@
for n; do # loop over the remaining names in $@
[ ! -f "$n" ] && continue # skip names of things that are not regular files
p=${n%.*} # get the prefix of the file path up to the last dot
s=${n##*.} # get the extension of the file after the last dot
# rename the file if there's not already a file with that same name
[ ! -e "${p}_$suffix.$s" ] && mv "$n" "${p}_$suffix.$s"
done
使用bash
,您可以对目录中的文件运行此命令,如下所示:
$ shopt -s extglob
$ ./script.sh "notZip" !(*.zip)
通过extglob
在 中设置 shell 选项bash
,!(*.zip)
将匹配当前目录中不以 结尾的所有名称.zip
。
答案2
寻找+巴什方法:
export suffix="test"
A)与查找-exec
操作:
find your_folder -type f ! -name "*.zip" -exec bash -c 'f=$1; if [[ "$f" =~ .*\.[^.]*$ ]]; then ext=".${f##*\.}"; else ext=""; fi; mv "$f" "${f%.*}_$suffix$ext"' x {} \;
乙) 或者使用 bashwhile
循环:
find your_folder/ -type f ! -name "*.zip" -print0 | while read -d $'\0' f; do
if [[ "$f" =~ .*\.[^.]*$ ]]; then
ext=".${f##*\.}"
else
ext=""
fi
mv "$f" "${f%.*}_$suffix$ext"
done
答案3
在bash中:
shopt -s extglob
suffix=yoursuffix
for entry in !(*.zip)
do
[[ -f "$entry" ]] || continue
base=${entry%.*}
if [[ "$entry" =~ \. ]]
then
ext=${entry##*.}
echo mv -- "$entry" "${base}_${suffix}.${ext}"
else
echo mv -- "$entry" "${base}_${suffix}"
fi
done
echo
当您觉得合适时将其删除。
测试用例:
touch a.zip b.zip foo bar file.csv a.file.csv 'test case' 'test case.csv'
mkdir baz
示例输出:
mv -- a.file.csv a.file_yoursuffix.csv
mv -- bar bar_yoursuffix
mv -- file.csv file_yoursuffix.csv
mv -- foo foo_yoursuffix
mv -- scr scr_yoursuffix
mv -- test case test case_yoursuffix
mv -- test case.csv test case_yoursuffix.csv
...跳过目录baz
,但适当地重命名 foo 和 bar 。