Bash 从find-execdir中的文件名中删除

Bash 从find-execdir中的文件名中删除,bash,Bash,整个故事:我正在编写脚本,将所有文件从一个目录链接到另一个目录。新文件名将包含原始目录名。此时我使用find和-execdir选项 这就是我想使用它的方式: ./linkPictures.sh 2017_wien 2017/10 它将在2017/10中创建一个符号链接2017\u wien\u picture.jpg,指向文件2017\u wien/picture.jpg 这是我当前的脚本: #!/bin/bash UPLOAD="/var/www/wordpress/wp-content/u

整个故事:我正在编写脚本,将所有文件从一个目录链接到另一个目录。新文件名将包含原始目录名。此时我使用
find
-execdir
选项

这就是我想使用它的方式:

./linkPictures.sh 2017_wien 2017/10
它将在
2017/10
中创建一个符号链接
2017\u wien\u picture.jpg
,指向文件
2017\u wien/picture.jpg

这是我当前的脚本:

#!/bin/bash
UPLOAD="/var/www/wordpress/wp-content/uploads"
SOURCE="$UPLOAD/photo-gallery/$1/"
DEST="$UPLOAD/$2/"
find $SOURCE -type f -execdir echo ln -s {} $DEST/"$1"_{} ";"
它打印:

ln -s ./DSC03278.JPG /var/www/wordpress/wp-content/uploads/2017/10/pokus_./DSC03278.JPG
这就是我想要的:

ln -s ./DSC03278.JPG /var/www/wordpress/wp-content/uploads/2017/10/pokus_DSC03278.JPG

如何实施?我不知道如何将
basename
合并到剥离中。/。

您可以将此
find
bash-c
一起使用:

find $SOURCE -type f -execdir bash -c 'echo ln -s "$2" "/$DEST/$1"_${2#./}' - "$1" '{}'  \;
  • ${2#./}
    将从
    find
    命令输出的每个条目中剥离开始的
    /
  • $1
    将按原样传递给
    bash-c
    命令行
如果您有大量文件要处理,我建议使用此
while loop
使用进程替换以加快执行,因为它不会为每个文件生成新的bash。此外,它还将处理带有空格和其他特殊字符的文件名:

while IFS= read -r file; do
    echo ln -s "$file" "/$DEST/${1}_${file#./}"
done < <(find "$SOURCE" -type f -print0)
而IFS=read-r文件;做
echo ln-s“$file”“/$DEST/${1}{u${file}./}”

完成<要在
{}
上运行
basename
,您需要通过
sh
执行命令:

find "$SOURCE" -type f -execdir sh -c "echo ln -s '{}' \"$DEST/${1}_\$(basename \"{}\")\"" ";"
这不会赢得任何速度竞赛(因为每个文件都有
sh
),但它会起作用


所有的引用看起来可能有点疯狂,但有必要确保可能包含空格的文件的安全。

我建议使用
find-printf“%f\n”
xargs
。谢谢,它非常有效!我最初尝试使用“``运行basename,所以非常接近。@LeosLiterak我看到了您的另一个问题。在这一点上,还有一个额外的提示:始终使用
$(…)
,永远不要使用过时的反勾号。