Unixが番号順にリストされるようにファイル名を入力します。

Unixが番号順にリストされるようにファイル名を入力します。

次の形式の複数のファイルを含むフォルダがあります。

C Block Scan copy 1.pdf
C Block Scan copy 2.pdf
C Block Scan copy 3.pdf
C Block Scan copy 4.pdf
.
.
.

ls私が持っている問題の1つは、Unixを実行するときにそれらを次のようにリストすることです。

C Block Scan copy 1.pdf
C Block Scan copy 10.pdf
C Block Scan copy 11.pdf
C Block Scan copy 12.pdf
.
.
.

Unixが(希望的に)順番にリストできるように数字を埋めたいと思います。

C Block Scan copy 01.pdf
C Block Scan copy 02.pdf
C Block Scan copy 03.pdf
.
.
.
C Block Scan copy 09.pdf
C Block Scan copy 10.pdf
C Block Scan copy 11.pdf
C Block Scan copy 12.pdf
.
.
.

同様の問題がある投稿を見つけましたファイル名の数字を固定長でパッドしかし、私の状況に彼らのソリューションを適用しようとしましたが、正常に動作しませんでした。私が試したことは次のとおりです。

for f in *.pdf; do
    int=`basename $f .pdf | cut -d '.' -f 2`
    new_name=`printf "file.%0.2i.pdf\n” $int`
    [ ! -f $new_name ] && mv $f $new_name
done

私はこれが私の状況に対する彼らの解決策を盲目的に適用したことを認めています。私は基本的な構文を実際に理解しておらず、StackExchangeで投稿にコメントするのに十分なランクを取らないので、気にしません。

私はシェルスクリプトに初めて触れたので、構文の意味の説明が役に立ちます。

役に立つ場合は、macOS Mojave 10.14.6を使用しており、Brewがインストールされています。

よろしくお願いします。

答え1

使用zsh(現在のmacOSのデフォルトユーザーシェル):

autoload zmv # best in ~/.zshrc
zmv '(* )([0-9].pdf)' '${1}0$2'

答え2

これにより、現在のディレクトリで名前が質問に記載されているパターンに従うすべての「* .pdf」ファイルを見つけ、同じ名前に名前を変更しますが、数字は2桁で埋められます。

#!/usr/bin/env bash

shopt -s nullglob

for f in *[[:space:]][0-9].pdf; do
    int="$(basename "$f" | rev | cut -d ' ' -f1 | rev | cut -d . -f1)"
    name="$(basename "$f" | rev | cut -d ' ' -f2- | rev)"
    padded_int="$(printf "%02d\n" "$int")"

    echo mv "$f" "$(printf "%s %s.pdf" "$name" "$padded_int")"

done

実際に実行する前に削除してくださいecho。ただし、必要に応じて動作することを確認するには、まずそのまま実行してください。上記のスクリプトを次の場所に保存する使用例:mvmvpdf.sh

$ for i in {1..10}; do touch "C Block Scan copy $i.pdf"; done
$ ./pdf.sh
mv C Block Scan copy 1.pdf C Block Scan copy 01.pdf
mv C Block Scan copy 2.pdf C Block Scan copy 02.pdf
mv C Block Scan copy 3.pdf C Block Scan copy 03.pdf
mv C Block Scan copy 4.pdf C Block Scan copy 04.pdf
mv C Block Scan copy 5.pdf C Block Scan copy 05.pdf
mv C Block Scan copy 6.pdf C Block Scan copy 06.pdf
mv C Block Scan copy 7.pdf C Block Scan copy 07.pdf
mv C Block Scan copy 8.pdf C Block Scan copy 08.pdf
mv C Block Scan copy 9.pdf C Block Scan copy 09.pdf

最初の行:

#!/usr/bin/env bash

シェルボーン。また、envその特性

この行

shopt -s nullglob

セット空のボール 住宅オプション これはリンクされたウェブサイトでも説明されています。

nullglob

If set, Bash allows filename patterns which match no files to
expand to a null string, rather than themselves.

パターン条件に一致するファイルがない場合は、forループが起動しないようにする必要があります。

for f in *[[:space:]][0-9].pdf; do

*[[:space:]][0-9].pdf名前が任意の数の文字、スペース、数字、次に終わるファイルを見つけることを意味するシェルモードです。.pdf。ループ内には、$f処理された.pdfファイルの名前が格納されます。

ここ

int="$(basename "$f" | rev | cut -d ' ' -f1 | rev | cut -d . -f1)"

私たちは使用コマンドの置き換え 与えられたファイル名の整数部分を変数に割り当てます。ターミナルでパイプラインの内容をbasename表示して再現できます。man basename

$ f='C Block Scan copy 1.pdf'
$ echo basename "$f" | rev | cut -d ' ' -f1 | rev | cut -d . -f1
1
$ f='C Block Scan copy 5.pdf'
$ echo basename "$f" | rev | cut -d ' ' -f1 | rev | cut -d . -f1
5

(参考$としてコマンドラインプロンプト コマンドの一部ではなく、新しい行の開始を示すために使用されます。

次の行に

name="$(basename "$f" | rev | cut -d ' ' -f2- | rev)"

.pdfから数字の前のすべての名前部分を抽出します。

次の行に

padded_int="$(printf "%02d\n" "$int")"

Bashの組み込みコマンドを使用して、変数を入力してprintf保存します。ループの最後の行に$intpadded_int

echo mv "$f" "$(printf "%s %s.pdf" "$name" "$padded_int")"

echoもちろん、コマンド置換を使用して実際の名前変更をやり直してくださいprintf 。 Cと同様に、printf2つのフォーマット指定子と2つの対応する引数と一緒に使用されます。%s

最後の行

done

ループを閉じます。

答え3

PEパラメータ拡張を使用します。mvシェルの外部ツールにのみ適用されますbash

#!/usr/bin/env bash

shopt -s nullglob

for f in *[[:space:]][0-9].pdf; do
  n=${f##* }  ##: Remain only 1.pdf, 2.pdf etc.
  n=0${n%.*}  ##: Remain only 1 , 2 etc. and pad 0 so it will be 01, 02 ..
  echo mv -v "$f" "${f/[0-9]/"$n"}"  ##: Replace all [0-9] with the value of "$n"
done

関連情報