如何 GREP 文件名的子字符串以重命名文件?

How to GREP a substring of a filename for renaming files?

我有很多文件以 example1_partofEx1A_individualfile_name.fil 命名。

我已经将文件组织成一个目录结构,所以路径是 ./example1/partofEx1A/example1_partofEx1A_individualfile_name.fil

我正在尝试编写一个可以从文件名中删除不必要信​​息的脚本。我基本上想 grep 'individualfile' 部分,这样我就可以使用循环和 mv.

我没有编写脚本的经验,只有一些 matlab 经验。使用 ubuntu 或 macOS。有什么建议吗?

假设三部分(前两个删除,第三个保留)总是用下划线分隔,这可能是一个可能的解决方案:

for f in /path/to/rootdir/*; do
    if [[ -f $f ]]; then
        mv "$f" "$(echo "$f" | sed "s/\/.*_.*_/\//")"
    fi
done

其中 /path/to/rootdir 是您的结构的根目录。

可能是这样的:

#!/bin/bash

cd /path/to/rootdir || exit

for file in *.fil;do
    IFS=_ read dir1 dir2 individual <<<"$file"
    if [ "$individual" ] ;then
        test -d "$dir1/$dir2" || mkdir -p "$dir1/$dir2"
#       mv -v "$file" "$dir1/$dir2/$individual"
        mv -vt "$dir1/$dir2" "$file"
      fi
  done

根据 Charles Duffy's comment 的建议,我已将 -p 标志添加到 mkdir 以防止竞争条件。

#!/usr/bin/env bash
for f in ./*/*/*; do
  [[ $f =~ ^[.]/([^/]+)/([^/]+)/(.*) ]] || continue
  dir1=${BASH_REMATCH[1]}
  dir2=${BASH_REMATCH[2]}
  filename=${BASH_REMATCH[3]}

  [[ $filename = "${dir1}_${dir2}_"* ]] || continue
  new_name=${filename#"${dir1}_${dir2}_"}
  mv -- "$f" "${dir1}/${dir2}/$new_name"
done

测试如下:

testdir="$(mktemp -d)"
cd "$testdir" || exit
mkdir -p ./dirA/dirB
touch dirA/dirB/dirA_dirB_hello_world.txt
touch dirA/dirB/other_content_here.txt

for f in ./*/*/*; do
  [[ $f =~ ^[.]/([^/]+)/([^/]+)/(.*) ]] || continue
  dir1=${BASH_REMATCH[1]}
  dir2=${BASH_REMATCH[2]}
  filename=${BASH_REMATCH[3]}

  [[ $filename = "${dir1}_${dir2}_"* ]] || continue
  new_name=${filename#"${dir1}_${dir2}_"}
  mv -- "$f" "${dir1}/${dir2}/$new_name"
done

...目录包含:

./dirA
./dirA/dirB
./dirA/dirB/hello_world.txt
./dirA/dirB/other_content_here.txt