使用bash将文件复制到指定文件夹

3
我有一个带有相当多子文件夹的文件夹。在一些子文件夹中,我有一个folder.jpg图片。我的目标是找到包含图片的文件夹,并将它复制到所有具有相同艺术家和专辑信息的其他子文件夹中,然后继续下一个专辑等等。
所有文件夹的结构都是"艺术家-年份-专辑-[编码信息]"。 我已经创建了一个非常简单的一行命令来查找拥有该文件的文件夹,但是我陷入了困境。
ls -F | grep / | while read folders;do find "$folders" -name folder.jpg; done

有人有解决这个问题的好建议或想法吗?还是可以给我一些前进的指引?

编辑:

首先,我对此完全不了解(就像你看得出来的那样),所以请耐心。

好吧,让我再更详细地说明一下。

我有一个文件夹结构,看起来像这样:

artist1 - year - album - [flac]
artist1 - year - album - [mp3]
artist1 - year - album - [AAC]
artist2 - year - album - [flac]
etc

我喜欢循环遍历相同艺术家和专辑信息的文件夹集,查找folder.jpg文件。当我找到该文件时,我会将其复制到同一集合中的所有其他文件夹中。
例如,如果我在artist1-year-album-[flac]文件夹中找到一个folder.jpg,我希望将该folder.jpg复制到artist1-year-album-[mp3]artist1-year-album-[AAC],但不要复制到artist2-year-album-[flac]
然后继续循环直到处理完所有集合。我真的希望这样更容易理解我要做什么 :)

是否总是只有一个子文件夹带有folder.jpg?如果有多个folder.jpg会发生什么?您想保留原始文件还是不在意? - Cougar
可以有多个folder.jpg,但只要覆盖它的那个来自同一“集”(艺术家-专辑),我就不在乎保留任何“原始”文件。脚本的重要性/思想在于不会将错误的folder.jpg复制到错误的文件夹集中,并且所有文件夹都会得到正确的folder.jpg的副本。这有意义吗? - Franko
简单的 find . -name folder.jpg 不就够了吗?看起来你把事情复杂化了... 另外,如果你能提供一个这样的例子:"有这些文件夹,其中一些有 folders.jpg,另一些没有,我想要发生......" 那就好了,因为我并不明白你到底想要什么。 - user1046334
感谢您的反馈。我已经更新了原始帖子,并添加了一些更多的信息,希望这能对您有所帮助 :) - Franko
你可以使用 cut 命令来提取目录名称的共同部分。 - BitSchupser
这是一个Python脚本,可以解决稍微复杂一些的问题(它不假设所有(艺术家,专辑)目录都在同一个目录中)(未经测试)。 - jfs
2个回答

1
IFS='
'
FLDRS=`find . -name folder.jpg | grep -v ./folder.jpg | sed -e 's@/folder\.jpg$@@`
for F in $FLDRS; do
  NOENC=`echo "$F" | sed -e 's/\[.*$//'`
  for DST in "$NOENC*"; do
    if [ -d "$DST" -a ! -f "$DST/folder.jpg" ]; then
      cp "$F/folder.jpg" "$DST"
    fi
  done
done

对于已经包含所有编码的folder.jpg的集合来说,这种方法效率较低,但除非出现错误,否则它应该能够完成工作。


IFS会处理它,同时引用每个包含变量的文件名。 - user1046334
我现在已经测试过了,出现了以下错误:command substitution: line 3: unexpected EOF while looking for matching ''andcommand substitution: line 4: syntax error: unexpected end of file `我猜测是在 's@/folder\.jpg$@@ 后面缺少了一个 ',但即使添加了这个符号,脚本也没有复制任何 folder.jpg 文件。不过我喜欢这个例子。希望它能让我更深入地了解如何为这种任务构建 shell 脚本。 - Franko
@Franko:是的,抱歉。如果还是不行,我现在不知道原因(我只是写了它,没测试过)。你可以在脚本中添加一些回显来显示变量的实际值,并跟踪它是否循环……希望你能想办法让它工作起来。 - user1046334
我会尝试理解并修正它以使其工作。我想我得先研究一下sed命令。无论如何,感谢您的帮助。非常感激! - Franko
@Franko:也许你的 grep 急切地将 ./folder.jpg 解释为正则表达式而不是普通字符串,因此匹配了每一行 :-/ 根据我的经验,只有 grep -E 或 egrep 会像这样工作。如果你可以保证主文件夹中没有 folder.jpg,你可以省略它;或者去 man find,寻找 min-depth 或类似的东西并将其设置为 1;这样你也可以省略 grep。它仅用于过滤掉主目录下的 ./folder.jpg,即 folder.jpg。另一个可能性是直接使用正则表达式 grep -E -v '^\.folders\.jpg$' 进行过滤。 - user1046334
显示剩余7条评论

1

我知道这不是最有效或正确的代码,但对我来说它完成了工作,并且我在正确的文件夹中得到了正确的folder.jpg。

IFS='
'

source=( `find . -name folder.jpg |  sed 's/^..//' | sort -u` )
   for s in ${source[@]}
        do

          fullname=(`echo $s | cut -d'/' -f1 | sort -u`)
          checkname=`echo $fullname | cut -d'[' -f1 | sort -u`
          match=( `find . -name "$checkname*" | sed 's/^..//' | sort -u` )

             for a in ${match[@]}
                do
                    if [[ "$a" == "$fullname" ]];
                    then
                        echo $a 'not copied'
                    else
                        echo $a
                        #echo $match '*M*'
                        cp $s "$a/folder.jpg"

                    fi    
                done


    done

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接