在 Unix 中如何将文件移动到具有相似名称的文件夹中?

How do I move files into folders with similar names in Unix?

很抱歉,如果之前有人问过这个问题,我只是不知道如何将其表达为搜索查询。

我有一组文件夹,如下所示:

Brain - Amygdala/                 Brain - Spinal cord (cervical c-1)/  Skin - Sun Exposed (Lower leg)/
Brain - Caudate (basal ganglia)/  Lung/                                Whole Blood/

我还有一组这样的文件:

Brain_Amygdala.v7.covariates_output.txt                  Skin_Not_Sun_Exposed_Suprapubic.v7.covariates_output.txt
Brain_Caudate_basal_ganglia.v7.covariates_output.txt     Skin_Sun_Exposed_Lower_leg.v7.covariates_output.txt
Brain_Spinal_cord_cervical_c-1.v7.covariates_output.txt  Whole_Blood.v7.covariates_output.txt

如您所见,这些文件与其名称中的目录并不完全匹配。例如,Brain_Amygdala.v7.covariates_output.txtBrain - Amygdala/ 并不完全相同。即使我们要从协变量文件中删除组织名称,Brain_Amygdala 的格式也与其相应的文件夹不同。

Whole Blood/。它不同于 Whole_Blood.v7.covariates_output.txt,即使您要从协变量文件 Whole_Blood 中分离出组织名称。

然而,我想做的是将这些组织文件中的每一个移动到它们对应的文件夹中。如果您注意到,协变量文件以文件名中第一个点 . 之前的组织命名。它们由下划线 _ 分隔。 我的想法是将文件名的第一个 . 前的前几个词分开,这样我就可以轻松地将它移动到相应的文件中.

例如

Brain_Amygdala.v7.covariates_output.txt -> Brain*Amygdala [mv]-> Brain*Amygdala/

a) 我不确定如何隔离文件名

中第一个 . 之前的文件名的第一个单词

b) 如果我这样做,我不知道如何在每个单词之间插入通配符并将其与相应的文件夹匹配。

但是,我完全愿意接受其他方式来做这样的事情。

不是完整的答案,但它应该可以解决您的一些疑虑:

a) 隔离字符串的第一个单词,直到第一个 .:使用 Parameter Expansions

string=Brain_Amygdala.v7.covariates_output.txt
until_dot=${string%%.*}
echo "$until_dot"

将输出 Brain_Amygdala(我们将其保存在变量 until_dot 中)。

b) 您可能希望使用 ${parameter/pattern/string} 参数扩展:

# Replace all non-alphabetic characters by the glob *
glob_pattern=${until_dot//[^[:alpha:]]/*}
echo "$glob_pattern"

会输出(变量同上)Brain*Amygdala

c) 要使用所有这些:首先确定可能的目标并进行一些基本检查可能是个好主意:

# Use nullglob to have non matching glob expand to nothing
shopt -s nullglob
# DO NOT USE QUOTES IN THE FOLLOWING EXPANSION:
# the variable is actually a glob!
# Could also do dirs=( $glob_pattern*/ ) to check if directory
dirs=( $glob_pattern/ )

# Now check how many matches there are:
if ((${#dirs[@]} == 0)); then
    echo >&2 "No matches for $glob_pattern"
elif ((${#dirs[@]} > 1)); then
    echo >&2 "More than one matches for $glob_pattern: ${dirs[@]}"
else
    echo "All good!"
    # Remove the echo to actually perform the move
    echo mv "$string" "${dirs[0]}"
fi

我不知道你的数据如何有效地符合这些,但我希望这个答案能真正回答你的一些问题! (要了解有关参数扩展的更多信息,请阅读并试验我给您的参考文献 link)。