用sed减少命令

时间:2012-11-28 14:33:16

标签: bash sed

如果没有&&可以将此命令减少到一行,我只是感兴趣吗?

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

3 个答案:

答案 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之后到行尾的所有内容