
次のようにファイルを移動しようとしています:
...
DLG023-00-01-sprite.TextGrid.json
DLG023-00-01.prosody.json
DLG023-01-01-sprite.ogg
DLG023-00-02-sprite.TextGrid.json
DLG023-00-02.prosody.json
DLG023-01-02-sprite.ogg
...
DLG028-00-01-sprite.TextGrid.json
DLG028-00-01.prosody.json
DLG028-01-01-sprite.ogg
...
それぞれのフォルダーに移動します。たとえば、ファイルが ;dialogue023/
で始まる場合は に移動し、 ;で始まる場合DLG023
は に移動します。dialogue024/
DLG024
すべてのファイルとディレクトリは同じレベルにあります。
つまり、次のようなコマンドを生成しようとしています。
mv DLG023-00-01-sprite.ogg dialogue023/
ファイル名から最初の数字を抽出するにはどうすればよいですか?
これまでのところ、私はこれを持っています:
for i in DLG*-*-*-sprite.ogg; do echo "${i//[^0-9]}";done
しかし、最初の数字 (例: 23) だけが必要なのに、すべての数字 (例: 230001) が出力されます。
答え1
OS X を使用していると仮定していますが、OS X-t
には のオプションがありませんmv
。スクリプトが何千ものファイルを処理している場合、これは非常に遅くなります。
for file in DLG*; do
# Extract the three digits after DLG
getnum=${file%%-*}
getnum=${getnum#???}
# make the directory dialogue### or exit if there is an error
echo mkdir -p "dialogue${getnum}" || exit
echo mv "$file" "dialogue${getnum}"
done
出力が満足できるものであれば、echo
前の部分を削除します。mkdir
mv
答え2
次のようにして mv コマンドを生成できます。
for f in DLG*; do echo "$f" | sed 's/DLG\([0-9]\+\).*/mv "\0" "dialogue\1\/"/g'; done
コマンドは次のように出力されます:
mv "DLG023-00-01.prosody.json" "dialogue023/"
[...]
mv "DLG028-00-01.prosody.json" "dialogue028/"
[...]
それが望みどおりであれば、その出力をパイプするだけでbash
実行されます。
for f in DLG*; do echo "$f" | sed 's/DLG\([0-9]\+\).*/mv "\0" "dialogue\1\/"/g'; done | bash
答え3
以下を使用した 1 行のソリューションfind
:
find . -name DLG* -exec bash -c 'DEST=$(echo "$0" | sed -r "s/DLG([0-9]+)-.*/dialogue\1/"); mkdir "$DEST"; mv "$0" "$DEST"' {} \;
find
DLG*
コマンドはこのディレクトリからファイルを検索します。- 結果ごとに
bash -c
文を実行します。
次の文ではbash
:
DEST=$(echo "$0" | sed -r "s/DLG([0-9]+)-.*/dialogue\1/");
find($0
) からすべての結果を選択し、sed
最初の-
(DLG([0-9]+)-.*)の前のすべての数字dialogue
を、その数字 (dialogue\1
) に置き換えて、 という変数に格納しますDEST
。mkdir "$DEST"
必要なフォルダーを作成します。mv "$0" "$DEST"'
ファイルをそのディレクトリに移動します。
答え4
いくつかのアイデア:
for i in DLG*-\*-\*-sprite.ogg; do echo "${i//[^0-9]}" | head -c 2; echo ;done
すべて同じ長さであることが確実な場合:
for i in DLG*-\*-\*-sprite.ogg; do echo "${i:3:3}" ;done