0

我只是感兴趣是否可以将此命令减少到一行而没有&&

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
4

3 回答 3

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}"' {} \;

它可以很好地处理不寻常的文件名。

于 2012-11-28T14:39:51.423 回答
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

这会将每个文件名包含在单引号中。

于 2012-11-28T14:44:09.630 回答
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到行尾的所有内容
于 2012-11-28T14:40:29.147 回答