如何复制和重命名“查找”功能Linux中找到的文件?


17

我有一个名为/home/user/temps487的文件夹。在每个文件夹中,我都有一个名为thumb.png的文件。

我想将所有名为thumb.png的文件复制到一个单独的文件夹,然后根据它们来自的文件夹来重命名它们。


重命名它们,如何?如果将目录定界符替换为下划线(_),则可能与已包含下划线的文件发生冲突。每个有效字符都是如此,在文件名中禁止的/和\ 0旁边,没有安全港-任何字符都可能产生冲突。
用户未知,

文件夹有子文件夹,还是只有普通的宽文件夹结构?
用户未知,

Answers:


8

干得好:

for file in /home/user/temps/*/thumb.png; do new_file=${file/temps/new_folder}; cp "$file" "${new_file/\/thumb/}"; done;

编辑:

顺便说一句,规范的智慧是,为此使用find一个坏主意-仅使用shell扩展更加可靠。另外,这是假设bash,但我认为这是一个安全的假设:)

编辑2:

为了清楚起见,我将其分解:

# shell-expansion to loop specified files
for file in /home/user/temps/*/thumb.png; do

    # replace 'temps' with 'new_folder' in the path
    # '/home/temps/abc/thumb.png' becomes '/home/new_folder/abc/thumb.png'
    new_file=${file/temps/new_folder};

    # drop '/thumb' from the path
    # '/home/new_folder/abc/thumb.png' becomes '/home/new_folder/abc.png'
    cp "$file" "${new_file/\/thumb/}";
done;

有关该${var/Pattern/Replacement}结构的详细信息,请参见此处

cp行中的引号对于处理文件名中的空格和换行符等非常重要。


new_file = new_folder?反斜杠前面的反斜杠的目的是什么new_file/\/thumb
用户未知,

1
@user:${VARIABLE/PATTTERN/REPLACEMENT}产生值,VARIABLE但模式由替换文本替换。这里的模式是/thumb/需要进行转义,使其看起来不像${new_file//PATTERN/REPLACEMENT},这使其成为全局替换而不是首次出现的替换),并且替换文本为空。
吉尔斯(Gilles)'所以

当然,现在我看到了。:)
用户未知

1
您假设487目录直接位于/home/user/temps,这在问题中还不清楚。如果不是,则需要find**
吉尔(Gilles)'所以

@Gilles-的确如此,这就是我阅读问题的方式。不过,我很欣赏这一点:)
simon

5

这适用于任意深度的子目录:

$ find temps/ -name "thumb.png" | while IFS= read -r NAME; do cp -v "$NAME" "separate/${NAME//\//_}"; done
`temps/thumb.png' -> `separate/temps_thumb.png'
`temps/dir3/thumb.png' -> `separate/temps_dir3_thumb.png'
`temps/dir3/dir31/thumb.png' -> `separate/temps_dir3_dir31_thumb.png'
`temps/dir3/dir32/thumb.png' -> `separate/temps_dir3_dir32_thumb.png'
`temps/dir1/thumb.png' -> `separate/temps_dir1_thumb.png'
`temps/dir2/thumb.png' -> `separate/temps_dir2_thumb.png'
`temps/dir2/dir21/thumb.png' -> `separate/temps_dir2_dir21_thumb.png'

有趣的是参数扩展 ${NAME//\//_}。它采用的内容NAME,并用替换每次出现/_

注意:结果取决于工作目录和用于查找的path参数。我从临时目录的父目录执行了命令。替换cpecho进行实验。


名称中包含换行符的文件失败。
用户未知

好吧,效果很好。还有一件事,我在一些子目录中也很少有压缩文件。也可以从那里提取imgae吗?记得'zip not tar'
Mirage

1

简短的帮助代码:

#!/bin/bash
#
# echo cp "$1" ../tmp/"${1//\//_}" 
#
mv "$1" ../tmp/"${1//\//_}"

让我们将其命名为“ deslash.sh”并使其可执行。调用它:

find -type f -name thumb.png -exec ./deslash.sh {} ";"    

如果存在冲突,它将失败

a/b/thumb.png # and 
a_b/thumb.png 

但这是不可避免的。


0

尝试这个

mkdir /home/user/thumbs
targDir=/home/user/thumbs

cd /home/user/temps

find . -type d | 
 while IFS="" read -r dir ; do
   if [[ -f "${dir}"/thumb.png ]] ; then
     echo mv -i "${dir}/thumb.png" "${targDir}/${dir}_thumb.png"
   fi
done

编辑

我添加了引号,以防您的任何目录名中都嵌入了空格字符。

我也改变了它,所以它只会打印出要执行的命令。检查脚本的输出,以确保所有文件/路径名看起来正确。如果确定要执行的命令没有问题,请删除echo


我在其他子文件夹中有一些png文件,可以使用
Mirage

对于我的“ A A”文件夹,它产生:mv -i ./A A/thumb.png ../tmp/.png-所有文件都以../tmp/.png结尾(../tmp是我的目标目录)。
用户未知

在上述代码中的所有变量周围加上引号和花括号,即“ $ {dir}”
shellter

@ Mirror51写道:“在更多子文件夹中的文件,将起作用”。是的,应该。您知道吗,您可以分别执行此脚本的每个步骤(或通过管道连接在一起时,每套管道)。您可以仅执行find -type d并查看输出。这样可以得到您期望的所有目录吗?如果没有,请添加一些输出以显示问题。祝好运。
shellter 2011年

不行 read dir执行分词,并从目录a\nba和b中将其作为两个实例,而掩蔽无法解决。
用户未知

-1

要复制,您需要命令cp,并且为linux重命名与移动文件相同,因此必须使用mv命令来进行复制。在Linux中,您必须始终指定从源(如果您在另一个文件夹中)到目标文件夹的整个路径。我会像这样,复制:

cp /source_path/file /destination_path/

或重命名或移动

mv /source_path/old_file /destination_path/new_name_file

这只是发布者问题的一小部分。现在解释如何遍历目录并复制缩略图:-)

OP想要使用find

是的,您是对的...我不知道我怎么了...
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.