我有一个包含大约1,700个文件的文件夹。它们都被命名为1.txt
或1497.txt
等。我想重命名所有文件,以便所有文件名都是四位数。
即,23.txt
变为0023.txt
。
什么是shell脚本才能执行此操作?或者一个相关的问题:如何使用grep仅匹配包含\d.txt
的行(即一个数字,然后一个句点,然后是字母txt
)?
这是我到目前为止所拥有的:
for a in [command i need help with]
do
mv $a 000$a
done
基本上,运行三次,使用命令找到一位数,两位数和三位数文件名(初始零的数量已更改)。
答案 0 :(得分:47)
尝试:
for a in [0-9]*.txt; do
mv $a `printf %04d.%s ${a%.*} ${a##*.}`
done
根据需要更改文件名模式([0-9]*.txt
)。
通用枚举重命名,不对初始文件名集做出任何假设:
X=1;
for i in *.txt; do
mv $i $(printf %04d.%s ${X%.*} ${i##*.})
let X="$X+1"
done
关于同一主题:
答案 1 :(得分:14)
使用有时与Perl一起安装的rename
(在某些情况下为prename
)脚本,您可以使用Perl表达式进行重命名。如果存在名称冲突,脚本将跳过重命名。
以下命令仅重命名具有四位或更少位数后跟“.txt”扩展名的文件。它不会重命名不严格符合该模式的文件。它不会截断包含四位以上数字的名称。
rename 'unless (/0+[0-9]{4}.txt/) {s/^([0-9]{1,3}\.txt)$/000$1/g;s/0*([0-9]{4}\..*)/$1/}' *
一些例子:
Original Becomes
1.txt 0001.txt
02.txt 0002.txt
123.txt 0123.txt
00000.txt 00000.txt
1.23.txt 1.23.txt
到目前为止给出的其他答案将尝试重命名不符合模式的文件,为包含非数字字符的文件名产生错误,执行产生名称冲突的重命名,尝试重命名具有空格的文件他们的名字和可能的其他问题。
答案 2 :(得分:12)
for a in *.txt; do
b=$(printf %04d.txt ${a%.txt})
if [ $a != $b ]; then
mv $a $b
fi
done
答案 3 :(得分:9)
一衬垫:
ls | awk '/^([0-9]+)\.txt$/ { printf("%s %04d.txt\n", $0, $1) }' | xargs -n2 mv
如何使用grep仅匹配包含\ d.txt的行(IE 1位数,然后是句点,然后是字母txt)?
grep -E '^[0-9]\.txt$'
答案 4 :(得分:4)
假设您的文件夹中包含数据类型为.dat的文件。只需将此代码复制到名为run.sh的文件中,通过运行chmode +x run.sh
使其可执行,然后使用./run.sh
执行:
#!/bin/bash
num=0
for i in *.dat
do
a=`printf "%05d" $num`
mv "$i" "filename_$a.dat"
let "num = $(($num + 1))"
done
这会将文件夹中的所有文件转换为filename_00000.dat
,filename_00001.dat
等。
答案 5 :(得分:1)
此版本还支持在数字之前(之后)处理字符串。但基本上你可以做任何正则表达式匹配+ printf只要你的awk支持它。它也支持文件名中的空白字符(换行符除外)。
for f in *.txt ;do
mv "$f" "$(
awk -v f="$f" '{
if ( match(f, /^([a-zA-Z_-]*)([0-9]+)(\..+)/, a)) {
printf("%s%04d%s", a[1], a[2], a[3])
} else {
print(f)
}
}' <<<''
)"
done
答案 6 :(得分:0)
要仅匹配单个数字文本文件,您可以执行...
$ ls | grep '[0-9]\.txt'
答案 7 :(得分:0)
单线提示:
while [ -f ./result/result`printf "%03d" $a`.txt ]; do a=$((a+1));done
RESULT=result/result`printf "%03d" $a`.txt
答案 8 :(得分:0)
即使存在带空格的文件名,也要提供一个谨慎编写的解决方案:
#!/usr/bin/env bash
pattern='%04d' # pad with four digits: change this to taste
# enable extglob syntax: +([[:digit:]]) means "one or more digits"
# enable the nullglob flag: If no matches exist, a glob returns nothing (not itself).
shopt -s extglob nullglob
for f in [[:digit:]]*; do # iterate over filenames that start with digits
suffix=${f##+([[:digit:]])} # find the suffix (everything after the last digit)
number=${f%"$suffix"} # find the number (everything before the suffix)
printf -v new "$pattern" "$number" "$suffix" # pad the number, then append the suffix
if [[ $f != "$new" ]]; then # if the result differs from the old name
mv -- "$f" "$new" # ...then rename the file.
fi
done
答案 9 :(得分:0)
默认情况下,从# Copyright 2004-2017 Tom Rothamel <pytom@bishoujo.us>
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation files
# (the "Software"), to deal in the Software without restriction,
# including without limitation the rights to use, copy, modify, merge,
# publish, distribute, sublicense, and/or sell copies of the Software,
# and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
##############################################################################
# Code that originated in 00mainmenu.rpy
init -1600 python hide:
# menus: Music to play at the main menu.
config.main_menu_music = None
# advanced: Callbacks to run at start.
config.start_callbacks = [ ]
# Transition that's used after the game is loaded.
config.after_load_transition = None
# menus: Transition that's used at the end of the splash screen, when
# it is shown.
config.end_splash_transition = None
# Should we start the game with scene black or just scene?
config.start_scene_black = False
# A save to automatically load, if it exists.
config.auto_load = None
# The language we use when the game starts. None remembers the user's
# choice of language, and defaults to the game's native language.
config.language = None
# Should we attempt to return to the menu we were on after a reload?
config.reload_menu = True
# Callbacks to run after load.
config.after_load_callbacks = [ ]
# Should we suppress overlay during the splashscreen?
config.splashscreen_suppress_overlay = True
init -1600 python:
def _init_language():
"""
Changes the default language. This is called automatically by
Ren'Py as it starts up.
"""
import os
if "RENPY_LANGUAGE" in os.environ:
language = os.environ["RENPY_LANGUAGE"]
elif config.language is not None:
language = config.language
else:
language = _preferences.language
renpy.change_language(language)
# This fixes up the context, if necessary, then calls the real
# after_load.
label _after_load:
python:
renpy.context()._menu = False
renpy.context()._main_menu = False
main_menu = False
_in_replay = None
renpy.execute_default_statement(False)
_init_language()
python hide:
for i in config.after_load_callbacks:
i()
if config.after_load_transition:
renpy.transition(config.after_load_transition, force=True)
menu = renpy.session.pop("_reload_screen", None)
if config.reload_menu and (menu is not None):
renpy.run(ShowMenu(menu))
if renpy.has_label("after_load"):
jump expression "after_load"
else:
return
# Ditto, for warp.
label _after_warp:
python:
renpy.context()._menu = False
renpy.context()._main_menu = False
main_menu = False
_in_replay = None
if renpy.has_label("after_warp"):
jump expression "after_warp"
else:
return
# Common code for _start and _start_replay.
label _start_store:
python hide:
store.main_menu = False
renpy.context()._menu = False
renpy.context()._main_menu = False
for i in config.start_callbacks:
i()
return
# Starts up a replay. This is called by renpy.game.call_replay, and
# is expected to be called with _in_replay True and
# renpy.execute_default_statement already called.
label _start_replay:
call _start_store
python:
renpy.execute_default_statement(False)
if config.start_scene_black:
scene black
else:
scene
$ _init_language()
$ renpy.block_rollback()
jump expression _in_replay
label _splashscreen:
python:
if config.splashscreen_suppress_overlay:
renpy.dynamic("suppress_overlay", "_confirm_quit")
suppress_overlay = True
_confirm_quit = False
jump expression "splashscreen"
# This is the true starting point of the program. Sssh... Don't
# tell anyone.
label _start:
call _start_store
python:
renpy.execute_default_statement(True)
# Predict the main menu. When a load occurs, the loaded data will
# overwrite the prediction requests.
if renpy.has_screen("main_menu"):
renpy.start_predict_screen("main_menu")
renpy.block_rollback()
call _gl_test
call _load_reload_game from _call__load_reload_game_1
python hide:
auto_load = renpy.os.environ.get("RENPY_AUTO_LOAD", config.auto_load)
if not _restart and auto_load and renpy.can_load(auto_load):
renpy.load(auto_load)
if config.start_scene_black:
scene black
else:
scene
if not _restart:
$ renpy.display.interface.with_none(overlay=False)
$ renpy.block_rollback()
$ _old_game_menu_screen = _game_menu_screen
$ _game_menu_screen = None
$ _old_history = _history
$ _history = False
if renpy.has_label("splashscreen") and (not _restart) and (not renpy.os.environ.get("RENPY_SKIP_SPLASHSCREEN", None)):
call _splashscreen from _call_splashscreen_1
$ _game_menu_screen = _old_game_menu_screen
$ del _old_game_menu_screen
$ _history = _old_history
$ del _old_history
$ renpy.block_rollback()
if config.main_menu_music:
$ renpy.music.play(config.main_menu_music, if_changed=True)
else:
$ renpy.music.stop()
$ renpy.music.stop(channel="movie")
# Clean out any residual scene from the splashscreen.
if config.start_scene_black:
scene black
else:
scene
python:
# Stop predicting the main menu, now that we're ready to show it.
if renpy.has_screen("main_menu"):
renpy.stop_predict_screen("main_menu")
# Implement config.window
_init_window()
# This has to be python, to deal with a case where _restart may
# change across a shift-reload.
python:
if _restart is None:
renpy.transition(config.end_splash_transition)
else:
renpy.transition(_restart[0])
renpy.game.context().force_checkpoint = True
renpy.jump(_restart[1])
label _invoke_main_menu:
# Again, this has to be python.
python:
if _restart:
renpy.call_in_new_context(_restart[2])
elif not renpy.os.environ.get("RENPY_SKIP_MAIN_MENU", False):
renpy.call_in_new_context("_main_menu")
# If the main menu returns, then start the game.
python start:
renpy.game.context().force_checkpoint = True
renpy.jump("start")
# At this point, we've been switched into a new context. So we
# initialize it.
label _main_menu(_main_menu_screen="_main_menu_screen"):
$ _enter_menu()
python:
renpy.dynamic("_load_prompt")
_load_prompt = False
renpy.context()._main_menu = True
store.main_menu = True
jump expression _main_menu_screen
# This is called to show the main menu to the user.
label _main_menu_screen:
# Let the user give code that runs in the main menu context before
# the main menu runs.
if renpy.has_label("before_main_menu"):
call expression "before_main_menu"
# Let the user completely override the main menu. (But please note
# it still lives in the menu context, rather than the game context.)
if renpy.has_label("main_menu"):
jump expression "main_menu"
# New name.
elif renpy.has_label("main_menu_screen"):
jump expression "main_menu_screen"
# Compatibility name.
elif renpy.has_label("_library_main_menu"):
jump expression "_library_main_menu"
return
软件包(至少在Ubuntu中)安装了rename.ul
命令。
它的用途是(对man进行重新命名。ul):
重命名[选项]表达式替换文件...
该命令将使用提供的文件的给定util-linux
替换expression
的第一次出现。
在形成命令时,您可以使用:
replacement
不进行任何更改,而是读取该命令将进行的更改。如果确定,只需重新执行命令,而无需使用-v(详细)和-n(无效)选项
对于您的情况,命令为:
rename.ul -nv replace-me with-this in-all?-these-files*