如何根据文件名中的子字符串移动目录中的文件

如何根据文件名中的子字符串移动目录中的文件

我对 Unix/Linux 系统中的脚本编写和工作非常陌生,所以我非常感谢任何帮助。我确信之前已经回答过这个问题,但我无法弄清楚为什么其他解决方案都不适用于我的情况。

我有一个目录,其中包含几个 gzip 压缩的 ASCII 文本文件。我需要根据文件名将它们分开,具体取决于名称的第 5 个和第 6 个位置上是否存在字符串rbitv3和。v4

以下是我的文件名在目录中的示例:

M07Zv3REP1_S442_L001_R1_001.fastq.gz  
M07Zv3REP1_S442_L001_R2_001.fastq.gz  
M18ZitREP3_S276_L001_R2_001.fastq.gz  
M10ZrbREP3_S535_L001_R1_001.fastq.gz  
M10ZrbREP3_S535_L001_R2_001.fastq.gz  
M09Zv4REP1_S300_L001_R1_001.fastq.gz  
M09Zv4REP1_S300_L001_R2_001.fastq.gz  

我尝试过使用许多不同的 grep 选项,但它们返回每个文件。例如

grep -FLZ "rb" *.fastq.gz

我想我将使用 xargs 将 grep 文件移动到新目录,但我坚持如何获取正确的压缩文件来匹配。问题可能在于 grep 正在每个 fastq 文件中搜索,在这种情况下,某处可能有“rb”或“it”,因此所有内容都会返回。

任何帮助深表感谢!

答案1

是的,正如您所说,该grep命令将搜索文件名内部。由于文件被压缩,它将作为二进制数据搜索它们,如果文件足够大,您一定会在那里找到大多数随机的双字符字符串。请注意,即使 thy 没有被压缩,您仍然可以在 fastq 质量行中找到这些字符串。

无论如何,grep这不是正确的工具,因为它搜索文件的内容而不是文件名。在这种情况下,您所需要的只是简单的 shell 通配符。如果像您所显示的示例中的情况一样,您可以 100% 确定字符串v3v4或之一的存在足以定义文件,您可以执行以下操作rbit

mkdir v3 v4 rb it
for pat in v3 v4 rb it; do mv -- *"$pat"*gz "$pat"/; done

如果您还需要考虑特定位置,以便v3不计算名称中包含但不在第五和第六位置的文件,则需要如下所示:

mkdir v3 v4 rb it
for file in *gz; do 
    pat=$(printf '%s' "$file" | cut -c 5-6)
    mv -- "$file" "$pat"/
done

相关内容