【问题标题】:copy files from mount point listed in a csv从 csv 中列出的挂载点复制文件
【发布时间】:2014-05-30 14:42:39
【问题描述】:

我需要通过挂载点将超过 100,000 个 img 从一台服务器移动到另一台服务器,我列出了一个 .csv 文件,我正在寻找脚本 csv 看起来像这样

"images1\002_0001\thumb",53717902.jpg,/www/images/002_0001/thumb/
"images1\002_0001\thumb",53717901.jpg,/www/images/002_0001/thumb/
"images1\002_0001\thumb",53717900.jpg,/www/images/002_0001/thumb/

逗号分隔我们有源名称和目标

我正在考虑使用 awk 将每个变量创建为变量

SOURCE=`awk -F ',' '{ print $1 }' test.csv`
IMGNAME=`awk -F ',' '{ print $2 }' test.csv`
DEST=`awk -F ',' '{ print $3 }' test.csv`

这是我卡住的地方,我的循环

while read line
do
    cp $SOURCE${IMGNAME} $DEST
done <test.csv

这已将找到的名字复制到所有目录中

【问题讨论】:

  • 请告诉我们它是否有效...

标签: bash loops unix awk copy


【解决方案1】:

您可以使用现有的并将变量声明移动到引用 $line 的循环中,或者您可以使用 IFS,如下所示。

   while IFS=, read -r src filename dest
   do
      cp $src${filename} $dest
   done <test.csv

【讨论】:

  • 这解决了内存问题
  • 同时读取 LINE do SOURCE=$(echo $LINE | awk -F ',' '{ print $1 }') DEST=$(echo $LINE | awk -F ',' '{ print $2 }') cp $SOURCE $DEST
【解决方案2】:

有很多方法可以做到,一些例子

  1. 如果目录字符串中没有空格:你甚至可以从 shell
    sed -E 's/"/cp /; s/",/\// ; s/,/ /;s/\\/\//g' test.csv | /bin/bash
    最好在尝试之前检查一下。你谈到了很多文件...
    sed -E 's/"/cp /; s/",/\// ; s/,/ /;s/\\/\//g' test.csv | less

  2. 目录名称的字符串中可能有空格,例如My Windows Like Dir Name。在这种情况下,您需要双引号(即使出于这个原因也有双引号......)
    你可以只使用awk(总是从shell)
    awk -F',' '{gsub(/"/, "", $1); gsub(/\\/, "/", $1); print "cp \""$1"/" $2"\" \"" $3"\""}' test.csv | /bin/bash
    或者是等价的
    awk -F',' '{gsub(/"/, "", $1); gsub(/\\/, "/", $1); printf ("cp \"%s/%s\" \"%s\"\n",$1,$2,$3)}' test.csv | /bin/bash
    总是提前检查,避免最后一个管道|/bin/bash,把| head -n 10 可能只有前10行。

脚本可以写成:

  while IFS=, read -r SOURCE IMGNAME DEST
  do
   SOURCE=( ${SOURCE//\\/\/} )         # Here you need to change "\" in "/"
   SOURCE=( ${SOURCE//\"/} )           # Here I like to kill ""
   cp  "${SOURCE}/${IMGNAME}" "$DEST"  # Here I put again ""
  done <test.csv

注意:我认为您需要在“/” unix 样式中更改“\” windows 样式。所以我要求替换规则。

【讨论】:

  • 太好了,这适用于较小的文件,但在我拥有的 4 百万行 csv 上运行它并且内存不足,还有什么更有效的吗?
  • 即使使用命令行命令,您是否也耗尽了内存?我将答案更新为仅使用一个命令或sed(不带"")或awk(带"")。如果你仍然完成了内存,请尝试在更多文件中split该文件,然后一个接一个地执行它们。 (通常,您可以将命令的输出重定向到文本文件&gt;NewCommandFile 而不是| /bash/bin。在您可以拆分该文件并执行一个小脚本后,一个接一个地执行它们... Dividi et英佩拉!)。
猜你喜欢
  • 2016-10-21
  • 2013-01-26
  • 1970-01-01
  • 2019-11-15
  • 2013-07-16
  • 1970-01-01
  • 1970-01-01
  • 2020-11-27
  • 2015-04-23
相关资源
最近更新 更多