在单行中以单引号查找recursive / xargs / cp / awk / sed /单引号

时间:2014-09-24 05:40:34

标签: shell awk sed xargs cp

我正在尝试创建一个shell一行,以递归方式查找目录中的所有jpeg。然后我想将它们全部复制到外部目录,同时根据它们的日期和时间重命名它们,然后附加一个随机整数,以避免覆盖具有相同时间戳的图像。

第一次尝试:

find /storage/sdcard0/tencent/MicroMsg/ -type f -iname '*.jpg' -print0 | xargs -0 sh -c 'for filename; do echo "$filename" && cp "$filename" $(echo /storage/primary/legacy/image3/$(stat $filename |awk '/Mod/ {print $2"_"$3}'|sed s/:/-/g)_$RANDOM.jpg);done' fnord

除此之外,上述方法不起作用,因为sh -c单引号中有单引号awk。

第二次尝试应该在没有sh -c的情况下做同样的事情,但在stat上给我这个错误:

stat: can't stat '': No such file or directory
/system/bin/sh: file: not found

第二次尝试:

find /storage/sdcard0/tencent/MicroMsg/ -type f -iname '*.jpg' -print0 | xargs -0 file cp "$file" $(echo /storage/primary/legacy/image3/$(stat "$file" | awk '/Mod/ {print $2"_"$3}'|sed s/:/-/g)_$RANDOM.jpg)

我认为第二次尝试的问题可能是太多的子弹?

任何人都可以帮我知道我在哪里出错吗?

另一方面说明:如果有人知道如何在复制文件时保留实际的修改日期/时间戳,我很乐意在这里投掷。

谢谢谢谢

2 个答案:

答案 0 :(得分:0)

如果是我的问题,我会创建一个脚本 - 称之为filecopy.sh - 就像这样:

TARGET="/storage/primary/legacy/image3"
for file in "$@"
do
    basetime=$(date +'%Y-%m-%d.%H-%M-%S' -d @$(stat -c '%Y' "$file"))
    cp "$file" "$TARGET/$basetime.$RANDOM.jpg"
done

basetime行运行stat以获取自The Epoch以来的文件修改时间(以秒为单位),然后将其与date一起用于将时间格式化为修改后的ISO 8601格式(使用-代替:.代替T)。然后使用它来创建目标文件名以及半随机数。

然后find命令变为:

SOURCE="/storage/sdcard0/tencent/MicroMsg"
find "$SOURCE" -type f -iname '*.jpg' -exec /path/to/filecopy.sh {} +

就个人而言,如果没有单独的shell脚本,我就不会尝试让它工作。它可以做到,但它不会是微不足道的:

SOURCE="/storage/sdcard0/tencent/MicroMsg"
find "$SOURCE" -type f -iname '*.jpg' -exec bash -c \
    'TARGET="/storage/primary/legacy/image3"
     for file in "$@"
     do
         basetime=$(date +%Y-%m-%d.%H-%M-%S -d @$(stat -c %Y "$file"))
         cp "$file" "$TARGET/$basetime.$RANDOM.jpg"
     done' command {} +

通过删除我在主shell脚本中使用的单引号,我已经采取了一些自由。它们是可选的,但我会在正常情况下自动使用它们。

答案 1 :(得分:0)

如果你有GNU Parallel>版本20140722你可以运行:

find . | parallel 'cp {} ../destdir/{= $a = int(10000*rand); $_ = `date -r "$_" +%FT%T"$a"`; chomp; =}'

它适用于包含'的文件名。和空格,但在包含"。

的文件名上失败

所有新计算机都有多个内核,但大多数程序本质上是串行的,因此不会使用多个内核。但是,许多任务都非常可并行化:

  • 在许多文件上运行相同的程序
  • 为文件中的每一行运行相同的程序
  • 为文件中的每个块运行相同的程序

GNU Parallel是一个通用的并行程序,可以很容易地在同一台机器上或在你有ssh访问权限的多台机器上并行运行作业。

如果要在4个CPU上运行32个不同的作业,并行化的直接方法是在每个CPU上运行8个作业:

Simple scheduling

GNU Parallel会在完成后生成一个新进程 - 保持CPU处于活动状态,从而节省时间:

GNU Parallel scheduling

<强>安装

个人安装不需要root访问权限。这可以在10秒内完成:

(wget -O - pi.dk/3 || curl pi.dk/3/ || fetch -o - http://pi.dk/3) | bash

有关其他安装选项,请参阅http://git.savannah.gnu.org/cgit/parallel.git/tree/README

了解详情

查看更多示例:http://www.gnu.org/software/parallel/man.html

观看介绍视频:https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1

完成教程:http://www.gnu.org/software/parallel/parallel_tutorial.html

注册电子邮件列表以获得支持:https://lists.gnu.org/mailman/listinfo/parallel