ここに最初に投稿します。最初の3つの文字とシリアル番号が同じディレクトリのファイルをグループ化する方法は?例えば
VHS-01-001.avi
VHS-01-002.avi
-------------
VHS-02-001.avi
VHS-02-002.avi
VHS-02-003.avi
---------
Hi8-01-001.avi
Hi8-01-002.avi
Hi8-01-003.avi
これにより、次のように関数から各ビデオファイルセットを渡すことができます。
encode(){
for avi in "$@"
do..
}
答え1
おそらくそれほどスマートなソリューションではないかもしれません。
- 名前でファイルを並べ替える
- 名前で繰り返す
最後のループの文字を比較します。
last="" ls -1 $1 | sort | while read file; do sub=${file:0:3} [ "$last" != "$sub" ] && { echo "NEW GROUP"; last="$sub"; } echo "[$sub] $file" done
コレクション配列内にファイル名をエコーする代わりに...
ちょうどアイデアです...出力例:
NEW GROUP
[Hi8] Hi8-01-002.avi
NEW GROUP
[VHS] VHS-01-001.avi
[VHS] VHS-01-002.avi
[VHS] VHS-02-002.avi
NEW GROUP
[XZU] XZU
編集1:ベースアンソニー・ゲガン答えは、ループの先頭にパイプを使用せずにbashワイルドカードを使用することです。彼のコメントを確認してください。
拡張スクリプト:
last=""
for file in *avi; do
sub=${file:0:3}
[ "$last" != "$sub" ] && { echo "NEW GROUP"; last="$sub"; }
echo "[$sub] $file"
done
編集2:
@ さんのリクエストに応じてトニー・チェン彼の3番目のコメントは次のとおりです。収集されたファイル名を関数に解析する簡単なソリューションを見つけることができます。これを行う方法はいくつかあります。そして私はbashスクリプトの経験があまりありません... ;)
#!/bin/bash
SOURCE_DIR="$1"
cd "$SOURCE_DIR" || { echo "could not read dir '$SOURCE_DIR'"; exit 1; }
function parseFiles() {
echo "parsing files:"
echo "$1"
}
last=""
declare -a fileGroup
for file in *avi; do
# first 3 chars of filename
sub=${file:0:3}
if test -z "$last"; then
# last is empty. first loop
last="$sub"
elif test "$last" != "$sub"; then
# new file group detected, parse collected
parseFiles "${fileGroup[*]}"
# reset array
fileGroup=()
last="$sub"
fi
# append name to array
fileGroup[${#fileGroup[@]}]=$file
done
parseFiles "${fileGroup[*]}"
答え2
そしてzsh
:
files=(???-??-*.avi)
for prefix (${(Mu)files#???-??-}) encode $prefix*.avi
(またはencode ${(M)files:#$prefix*}
)
GNUシェル(bash
)とそのツールは次のとおりです。
while IFS= read -u3 -rd '' prefix; do
encode "$prefix-"*.avi 3<&-
done 3< <(printf '%s\0' ???-??-*.avi | grep -oz '^...-..-' | sort -zu)
同じ原理。パターンに一致する現在のディレクトリのファイルのリストを取得し、一致する???-??-*.avi
部分(/)(regexp)を抽出し、一意の(/)次に対応するプレフィックスのリストを繰り返します。(M)
grep -o
???-??-
...-..-
(u)
sort -u