.Zip
ファイルとその他のファイル(すべてのファイルhave拡張子)があるディレクトリがあり、すべてのファイルにサフィックスを追加したいwithout.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)またはbash while
ループ:
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
の使用は少し危険です。参照 `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
_で終わらないすべての名前に一致します。
バッシュで:
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の名前を適切に変更します。
find <pathtodirectory> ! -name *.Zip | awk -v suff=$suffix -F\. '{ print $1"_"suff"."$2 }'
Findを使用してファイルを一覧表示し、awkを介して出力を解析できます。新しいサフィックスが含まれているファイルのリストに満足したら、awkのシステム関数を使用してawkからコマンドを再度実行し、作成してコマンドを実行します。
find <pathtodirectory> ! -name *.Zip | awk -v suff=$suffix -F\. '{ system("mv "$0" "$1"_"suff"."$2) }'
ただし、ソリューションにはコマンドインジェクションのリスクがあることに注意してください。また、ソリューションは、filename.extensionという構造を持つすべてのファイルに依存していることに注意してください。