我正在尝试移动这样的文件:
...
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,它没有该-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
一行解决方案使用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
) 中选择每个结果,并使用将第一个(DLG([0-9]+)-.*)sed
之前的所有数字替换为后面的这些数字 ( ),并将其放入名为 的变量中。-
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