これは私のサンプルファイルです。
user@linux:~$ ls -l | cut -d ' ' -f 10-
ch 10 - file.txt
ch 2 - file.txt
ch 3 - file.txt
ch 4a - file.txt
ch 5 - file.txt
user@linux:~$
0
任意の単一の数字を含めたい4a
ので、最終出力は次のようになります。
user@linux:~$ ls -l | cut -d ' ' -f 10-
ch 10 - file.txt
ch 02 - file.txt
ch 03 - file.txt
ch 04a - file.txt
ch 05 - file.txt
user@linux:~$
Linuxに組み込まれているツールを使ってこれは可能ですか?
答え1
模様
'ch '[1-9][!0-9]*'- file.txt'
変更する必要があるすべてのファイル名(表示されるファイル名の外部)と一致します。つまり、で始まり、ch
その後に1から9までの数字が続き、その後に数字以外の名前が続くすべてのファイル名と一致します。それ以降はすべての文字を受け入れ、名前はで終わる必要があります- file.txt
。
私たちはこれらのファイルを繰り返すことができます
for name in 'ch '[1-9][!0-9]*'- file.txt'; do
...
done
今、目標は0
そのビットの後に1つを挿入することですch
。ch
部分文字列を削除して次に置き換えますch 0
。
for name in 'ch '[1-9][!0-9]*'- file.txt'; do
newname='ch 0'${name#ch }
done
パラメータ置換は含まれている場合${name#ch }
に拡張されます(接頭辞が削除されます)。2 - file.txt
$name
ch 2 - file.txt
ch
その後、ファイル名を変更できます。
for name in 'ch '[1-9][!0-9]*'- file.txt'; do
newname='ch 0'${name#ch }
printf 'would rename "%s" into "%s"\n' "$name" "$newname"
# mv -i "$name" "$newname"
done
ループを一度実行したら、#
コメントアウトされたmv
コマンドを含む行を削除し、正しい操作を実行していることを確認してください。
表示されるファイル名が与えられると、上記のループが出力されます。
would rename "ch 2 - file.txt" into "ch 02 - file.txt"
would rename "ch 3 - file.txt" into "ch 03 - file.txt"
would rename "ch 4a - file.txt" into "ch 04a - file.txt"
would rename "ch 5 - file.txt" into "ch 05 - file.txt"
答え2
Lary Wallのrename
/ prename
(rename
Debian / Ubuntu、prename
RedHat / Fedora)の使用:
rename -n 's/^ch (\d) /ch 0$1 /' *
-n
練習実行の場合は、実際の実行のために削除(または「-v」に置き換えます)。
答え3
そしてzsh
:
autoload zmv # best in .zshrc
zmv -n '*[0-9]*' '${f//(#m)<->/${(l:2::0:)MATCH}}'
(-n
満足すれば削除(テスト実行))。
ef l
- すべての数字を幅2で埋めます。
それにも注意してください。カット幅が2の数字(1234-2.txt
)34-02.txt
。
どういう意味なのかわからない組み込み、特に関連してLinuxこれはカーネルだけです。autoload
zsh組み込みですがzmv
自動ロード可能関数は、デフォルトmv
では組み込みではないユーティリティーを呼び出します(ただし組み込みにすることはできますzmodload zsh/files
)。
答え4
これがあなたが探しているものです。
実行する必要がある操作は基本的に次のとおりです。
1. 数字が一桁か二桁かを確認します。 1 桁の数字で値が 9 以下の場合は、ファイル名を変更してください。これは次のように簡単なはずです。
(( someDigit <= 9 )) && [[ ${#someDigit'slength} -lt 2 ]]
2. 文字を含むファイルがあるので、次のように保存できます。
digit=$( echo $file | cut -d '-' -f1 | grep ch | awk '{print $2}' );
3. 次に、最初のオプションと比較できるように数値をフィルタリングします。tr -d
次のようにオプションで必要と思われるフィルタを追加します。
digitOnly=$( echo $digit | tr -d [a-Z] );
4. 次に、ファイル名を変更するディレクトリでループを実行します。これらすべてを実装すると、次のようになります。
for file in *file.txt; do
digit=$( echo $file | cut -d '-' -f1 | grep ch | awk '{print $2}' );
digitOnly=$( echo $digit | tr -d [a-Z] );
if (( digitOnly <= 9 )) && [[ ${#digitOnly} -lt 2 ]]; then
# mv "${file}" "ch 0${digit} - file.txt"
echo "'${file}' is renamed to 'ch 0${digit} - file.txt'";
fi
done
mvから#を削除して満足している場合は実行してください。あなたの例を見てください:
touch 'ch 10 - file.txt' 'ch 2 - file.txt' 'ch 3 - file.txt' 'ch 4a - file.txt' 'ch 5 - file.txt'
その後、スクリプトを実行するか、上記の内容をコピーして貼り付けると、次のような出力が得script
られます。bash
'ch 2 - file.txt' is renamed to 'ch 02 - file.txt'
'ch 3 - file.txt' is renamed to 'ch 03 - file.txt'
'ch 4a - file.txt' is renamed to 'ch 04a - file.txt'
'ch 5 - file.txt' is renamed to 'ch 05 - file.txt'
明らかに関数でラップし、ファイルパターンの検索などの入力を許可することでより一般的にすることもできますが、あなたの質問には必要ありません。したがって、現在の回答が質問に記載されている状況をうまく処理していると思います。