在文件夹名称中复制空格时,将文件夹名称附加到文件名

时间:2018-03-27 21:07:45

标签: string bash for-loop

我一直在使用循环将数据从外部组复制到我的工作目录,并将文件夹名称附加到文件名的开头。 for循环基于前一个问题。 Append part of folder name to all .gz within

由于我问了这个问题,外部小组简化了他们的文件夹结构,但是现在已经为某些文件夹名称添加了“(2)”(我没有能力影响该组命名文件的方式,它是一个巨人公司)。这个空间已经破坏了我的循环,我需要帮助修复它。

外部组的文件结构

  Samples/SampleName1/Files/SampleID1_uniqueNumber.gz
  Samples/SampleName2/Files/SampleID2_uniqueNumber.gz
  Samples/SampleName3/Files/SampleID3_uniqueNumber.gz
  Samples/SampleName3 (2)/Files/SampleID3_uniqueNumber.gz

我想要的目标文件夹(所有样本移动到单个目的地)

  SampleName1.SampleID1_uniqueNumber.gz
  SampleName2.SampleID2_uniqueNumber.gz
  SampleName3.SampleID3_uniqueNumber.gz
  SampleName3.SampleID3_uniqueNumber.gz

我当前的for循环正确复制除最后一个样本之外的所有内容。 uniqueNumber应该足够独特,以防止2 SampleName3相互覆盖。

   for f in ../pathToData/Samples/*/Files/*.gz;
    do s=${f##../pathToData/Samples/}; 
    s=${s%%/*};
    cp $f "/destinationFolder/"$s"."${f##*Files/};
    done

如何逃离空间,以便cp将“(2)”视为原始文件名的一部分,而不是“(2)”作为目标文件夹?

2 个答案:

答案 0 :(得分:1)

与某些编程语言不同,bash可以在引号内进行变量替换。要将变量作为单个参数传递,请将其括在引号中:

cp "$f" [...]

这也适用于命令的其余部分。它可以改写为:

cp "$f" "/destinationFolder/$s.${f##*Files/}";

答案 1 :(得分:1)

如果您想以自己的方式

for f in Samples/*/Files/*.gz; do
    s=${f##Samples/};
    s=${s%%/*};
    [[ $s =~ [[:space:]] ]] && continue
    echo cp "$f" "/destinationFolder/$s.${f##*Files/}"
done

(当它看起来足够好时删除echo命令)

但是你不需要任何循环,请看一下:

输入:

(你有一个欺骗文件:SampleName3.SampleID3_uniqueNumber.gz

$ tree Samples/
Samples/
├── SampleName1
│   └── Files
│       └── SampleID1_uniqueNumber.gz
├── SampleName2
│   └── Files
│       └── SampleID2_uniqueNumber.gz
├── SampleName3
│   └── Files
│       └── SampleID3_uniqueNumber.gz
└── SampleName3 (2)
    └── Files
        └── SampleID3_uniqueNumber.gz

8 directories, 4 files

shell中使用perl 的代码:

$ shopt -s globstar # enable recursion with '**' require bash --version >= 4
$ rename -n 's|^[^/]+/([^/\s]+)/Files/(.*\.gz)|$1.$2|' Samples/**/*.gz

输出:

Samples/SampleName1/Files/SampleID1_uniqueNumber.gz -> SampleName1.SampleID1_uniqueNumber.gz
Samples/SampleName2/Files/SampleID2_uniqueNumber.gz -> SampleName2.SampleID2_uniqueNumber.gz
Samples/SampleName3/Files/SampleID3_uniqueNumber.gz -> SampleName3.SampleID3_uniqueNumber.gz

当输出看起来不错时,删除-n开关。

warning 还有其他同名工具可能会或可能不会这样做,所以要小心。

如果您运行以下命令(GNU

$ file "$(readlink -f "$(type -p rename)")"

并且您的结果包含Perl script, ASCII text executable且不包含ELF,那么这似乎是正确的工具=)

如果没有,请将其设为Debian上的默认值(通常已经是这种情况)和Ubuntu之类的衍生物:

$ sudo update-alternatives --set rename /path/to/rename

/path/to/rename替换为perl rename可执行文件的路径。

如果您没有此命令,请搜索您的软件包管理器进行安装或do it manually(无代码......)

这个工具最初是由Perl的父亲Larry Wall编写的。