根据文件名的一部分将文件移动到子文件夹

根据文件名的一部分将文件移动到子文件夹

我的文件的文件名如下:

文本_2_2022-11-22_K03_10k_66_P578_B06_2999dl_text_693_coff_442.jpg 文本_2_2022-11-22_K03_10k_66_P578_B06_2999dl_text_693_coff_432.jpg 文本_2_2022-11 -22_K05_10k_66_P578_B06_2999dl_text_693_coff_175.jpg 文本_2_2022-11-22_K05_10k_66_P578_B06_2999dl_text_693_coff_832.jpg 文本_2_2022-11-22_K08_10k_ 66_P578_B06_2999dl_text_693_coff_322.jpg text_2_2022-11-22_K08_10k_66_P578_B06_2999dl_text_693_coff_975.jpg

我想创建子文件夹,例如:

K03_10k_66_P578_B06
K05_10k_66_P578_B06
K08_10k_66_P578_B06

然后将文件移动到正确的子文件夹中。

其他答案使用参数扩展,但考虑到更复杂的名称,我无法弄清楚如何执行此操作。因此,我编写了一个 grep/regex 命令来匹配文件名所需的部分,但无法在循环中实现它:

grep '[A-Z][0-9]*_[0-9]*[a-z]_[0-9]*_[A-Z][0-9]*_[A-Z][0-9]*'

我找到了类似的答案(1 2 3 4)到我的问题,但我的文件名比这些问题更复杂。

答案1

这在 bash 中使用参数扩展对我有用,将文件名拆分为多个部分,将部分部分重新连接到子文件夹名称中:

# get list of .jpg files to work on
shopt -s nullglob
file_list=( *.jpg )

# quick exit if there are no files
[[ ${#file_list[@]} -lt 1 ]] && {
  echo 'No *.jpg files found' >&2
  exit 1
}

# handle each file in the list
for orig_fname in "${file_list[@]}"
do
  # get filename without .xyz suffix
  fname="${orig_fname%.*}"

  # split file name into parts on underscores
  IFS=_ fname_parts=( $fname )

  # join parts 3,4,5,6,7 into the subfolder name
  # note: includes trailing _ in name
  printf -v subfolder '%s_' "${fname_parts[@]:3:5}"
  subfolder="${subfolder%_}"  # strip trailing _ from name

  # create subfolder if needed
  mkdir -v -p "$subfolder"

  # move file to its subfolder
  mv -v "$orig_fname" "$subfolder"
done

如果您不希望其信息在屏幕上滚动,请-vmkdir和命令中删除和 命令。mv

相关内容