Filenames

為所有沒有特定副檔名的文件添加後綴並保留文件副檔名

  • October 5, 2017

我有一個包含.zip文件和其他文件的目錄(所有文件都有副檔名),我想為所有沒有副檔名的文件添加後綴.zip。我可以選擇一個後綴並將其放入一個變數$suffix中,因此我嘗試了以下程式碼:

ls -I "*.zip"| xargs -I {} mv {} {}_"$suffix"

這列出了所有沒有.zip並且關閉的文件(但錯誤)。它在 上錯誤地產生以下結果file.csv

file.csv_suffix

我想要file_suffix.csv- 如何編輯我的程式碼以保留文件的副檔名?

find + bash方法:

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 {} \;


b ) 或使用 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

使用ls有點危險。請參閱為什麼 not 解析 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

引用自:https://unix.stackexchange.com/questions/396289