bash 在目录中递归查找和替换文件名

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9393607/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 21:40:58  来源:igfitidea点击:

Find and replace filename recursively in a directory

bash

提问by user1225606

I want to rename all the files in a folder which starts with 123_xxx.txtto xxx.txt.

我想重命名以123_xxx.txtto开头的文件夹中的所有文件xxx.txt

For example, my directory has:

例如,我的目录有:

123_xxx.txt
123_yyy.txt
123_zzz.txt

I want to rename all files as:

xxx.txt
yyy.txt
zzz.txt

I have seen some useful bash scripts in this forum but I'm still confused how to use it for my requirement.

我在这个论坛上看到了一些有用的 bash 脚本,但我仍然很困惑如何使用它来满足我的要求。

Let us suppose I use:

让我们假设我使用:

for file in `find -name '123_*.txt'` ; do mv $file {?.txt} ; done

Is this the correct way to do it?

这是正确的方法吗?

回答by sorpigal

Do it this way:

这样做:

find . -name '123*.txt' -type f -exec bash -c 'mv "" "${1/\/123_//}"' -- {} \;

Advantages:

好处:

  • No pipes, no reads, no chance of breaking on malformed filenames.
  • Only one non-standard tool or feature: bash.
  • 没有管道,没有读取,没有机会打破格式错误的文件名。
  • 只有一种非标准工具或功能:bash。

回答by user unknown

find -name "123*.txt" -exec rename 's/^123_//' {} ";" 

will do it. No AWK, no for, no xargs needed, but rename, a very useful command from the Perl lib. It is not always included with Linux, but is easy to install from the repos.

会做的。不需要 AWK,不需要 for,不需要 xargs,但是rename,一个来自 Perl 库的非常有用的命令。它并不总是包含在 Linux 中,但很容易从存储库安装。

回答by Kent

you could check 'rename' tool

你可以检查“重命名”工具

for example

例如

rename 's/^123_//' *.txt

or (gawk is needed)

或(需要呆呆)

find . -name '123_*.txt'|awk '{print "mv "
kent$  tree
.
|-- 123_a.txt
|-- 123_b.txt
|-- 123_c.txt
|-- 123_d.txt
|-- 123_e.txt
`-- u
    |-- 123_a.txt
    |-- 123_b.txt
    |-- 123_c.txt
    |-- 123_d.txt
    `-- 123_e.txt

1 directory, 10 files

kent$  find . -name '123_*.txt'|awk '{print "mv "
find -name "*foo*.filetype" -exec rename 's/foo/bar/' {} ";"
" "gensub(/\/123_(.*\.txt)$/,"/\1","g");}'|sh kent$ tree . |-- a.txt |-- b.txt |-- c.txt |-- d.txt |-- e.txt `-- u |-- a.txt |-- b.txt |-- c.txt |-- d.txt `-- e.txt 1 directory, 10 files
" "gensub(/\/123_(.*\.txt)$/,"/\1","g");}'|sh

test:

测试

find -name '123_*.txt' | while IFS= read -r file; do mv "$file" "${file#123_}"; done

回答by talsibony

In case you want to replace string in file name called foo to bar you can use this in linux ubuntu, change file type for your needs

如果您想将名为 foo 的文件名中的字符串替换为 bar,您可以在 linux ubuntu 中使用它,根据需要更改文件类型

find -name '123_*.txt' -print0 | while IFS= read -r -d '' file; do mv "$file" "${file#123_}"; done

回答by synthesizerpatel

A slight variation on Kent's that doesn't require gawk and is a little bit more readable, (although, thats debatable..)

Kent's 的一个细微变化,不需要呆呆,并且更具可读性,(虽然,那是有争议的..)

find . -name "123*" | awk '{a=$1; gsub(/123_/,""); printf "mv \"%s\" \"%s\"\n", a, $1}' | sh

find . -name "123*" | awk '{a=$1; gsub(/123_/,""); printf "mv \"%s\" \"%s\"\n", a, $1}' | sh

回答by glenn Hymanman

Provided you don't have newlines in your filenames:

如果您的文件名中没有换行符:

    find . -name '123*.txt' -type f -exec bash -c 'mv "" "${1/\/123_/\/hello_}"' -- {} \;

For a really safe way, provided your findsupports the -print0flag (GNU finddoes):

对于真正安全的方式,只要您find支持该-print0标志(GNU支持find):

#!/bin/bash

if test $# -lt 2; then
  echo "usage: `basename 
$ chmod +x recursive_replace_filename
$ ./recursive_replace_filename 123_ ""
` <to_replace> <replace_value>" fi for file in `find . -name "**" -type f`; do mv "'$file'" "${file/''/''}" done

回答by Pat O

To expand on Sorpigal's answer, if you want to replace the 123_with hello_, you could use

为了扩展Sorpigal 的答案,如果你想替换123_with hello_,你可以使用

find -name "*.txt" -exec rename -v "123_" ""  {} ";" 

回答by Rivenfall

You can make a little bash script for that. Create a file named recursive_replace_filenamewith this content :

您可以为此制作一个小 bash 脚本。创建一个recursive_replace_filename以此内容命名的文件:

  for fileType in d f
  do
    find  -type $fileType -iname "stringToSearch*" |while read file
    do
      mv $file $( sed -r "s/stringToSearch/stringToReplaceWith/" <<< $file )
    done
  done

Make executable an run:

使可执行文件运行:

##代码##

Keep note that this script can be dangerous, be sure you know what it's doing and in which folder you are executing it, and with which arguments. In this case, all files in the current folder, recursively, containing 123_will be renamed.

请注意,此脚本可能很危险,请确保您知道它在做什么以及在哪个文件夹中执行它,以及使用哪些参数。在这种情况下,当前文件夹中的所有文件,递归地,包含123_将被重命名。

回答by Paulo Fidalgo

Using rename from util-linux 2.28.2 I had to use a different syntaxt:

使用 util-linux 2.28.2 中的重命名我不得不使用不同的语法:

##代码##

回答by basslo

Tried the answer above but it didn't work for me cause i had the string inside folders and files name at the same time so here is what i did the following bash script:

尝试了上面的答案,但它对我不起作用,因为我同时在文件夹和文件名中有字符串,所以这是我执行以下 bash 脚本的操作:

##代码##

First i began by replacing inside folders name then inside files name.

首先,我首先替换内部文件夹名称,然后替换内部文件名。