我一直在使用循环将数据从外部组复制到我的工作目录,并将文件夹名称附加到文件名的开头。 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)”作为目标文件夹?
答案 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
$ 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
开关。
还有其他同名工具可能会或可能不会这样做,所以要小心。
如果您运行以下命令(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编写的。