如果没有&&
可以将此命令减少到一行,我只是感兴趣吗?
find /backup/daily.1/var/www/ -iname "*.jpg" -type f >> ~/backuppath.txt
sed 's|/backup/daily.1||g' ~/backuppath.txt > ~/wwwpath.txt
paste -d " " ~/backuppath.txt ~/wwwpath.txt > ~/files.txt
while read line; do cp $line; done < ~/files.txt
答案 0 :(得分:1)
这不涉及带空格的文件名。 (这不重要,我只是 说这是为了抢占不可避免的评论。)
find /backup/daily.1/var/www/ -iname "*.jpg" -type f |
while read name; do cp $name ${name#/backup/daily.1}; done
您也可以这样做:
find /backup/daily.1/var/www/ -iname "*.jpg" \
-type f -exec sh -c 'cp "$0" "${0#/backup/daily.1}"' {} \;
可以很好地处理异常文件名。
答案 1 :(得分:1)
我不会在一行上写它,但你可以不用中间文件:
find /backup/daily.1/var/www/ -iname "*.jpg" -type f |
sed 's%/backup/daily.1\(.*\)%cp & \1%' |
sh -x
sed
命令将文件名拆分为两个组件,/backup/daily.1
前缀和“其余”,并将完全复制命令替换为将原始名称复制到不带前缀的名称。 sed
的输出作为脚本提供给shell。
除非文件名包含shell元字符,空格或换行符,否则这应该可以正常工作。如果文件名中没有换行符或单引号,则可以提高弹性:
find /backup/daily.1/var/www/ -iname "*.jpg" -type f |
sed "s%/backup/daily.1\(.*\)%cp '&' '\1'%" |
sh -x
这将每个文件名包装在单引号中。
答案 2 :(得分:0)
find /backup/daily.1/var/www/ -iname "*.jpg" -type f \
| sed 's|^/backup/daily\.1\(.*\)$|\0 \1|' \
| ( while read origin dest; do cp "$origin" "$dest"; done)
在sed
表达式中:
\0
被匹配的字符串替换,这就是整个行就是这种情况\1
被子模式匹配\(.*\)
取代,即从/backup/daily.1
之后到行尾的所有内容