Linux shell脚本将前导零添加到文件名

时间:2010-09-08 22:14:28

标签: linux bash shell grep

我有一个包含大约1,700个文件的文件夹。它们都被命名为1.txt1497.txt等。我想重命名所有文件,以便所有文件名都是四位数。

即,23.txt变为0023.txt

什么是shell脚本才能执行此操作?或者一个相关的问题:如何使用grep仅匹配包含\d.txt的行(即一个数字,然后一个句点,然后是字母txt)?

这是我到目前为止所拥有的:

for a in [command i need help with]
do
  mv $a 000$a
done

基本上,运行三次,使用命令找到一位数,两位数和三位数文件名(初始零的数量已更改)。

10 个答案:

答案 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.datfilename_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*