特定の拡張子を持たないすべてのファイルにサフィックスを追加し、ファイル拡張子を保持します。

特定の拡張子を持たないすべてのファイルにサフィックスを追加し、ファイル拡張子を保持します。

.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

これにより、次のシェルスクリプトがこれらのファイルのリストとともに呼び出されます。

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ファイル数が多くなく、サブディレクトリへの再帰が必要ない場合(ファイル名ではなくエントリをスキップするように少し変更した場合)、上記のシェルスクリプトを独立して実行できます。

#!/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シェルオプションを設定すると、現在のディレクトリで終わらないすべての名前が一致します。bash!(*.zip).zip

答え2

探す+強く打つ方法:

export suffix="test"

)と検索-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

バッシュから:

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

...ディレクトリをスキップしてbazfooとbarの名前を適切に変更してください。

答え4

for f in `ls -I "*.zip" `; do mv $f `echo $f | cut -d '.' -f1`_suffix.`echo $f | cut -d '.' -f2` ; done ;

他の興味深いツールには、次のユーティリティがあります。名前を変更する

これは興味深い質問ですが、それもそうかもしれないことを意味します。尋ねる多くの時間ディレクトリを除外しないlsタスクを維持したことに注意してください。

関連情報