根据路径中的匹配模式提取子目录并创建符号链接

根据路径中的匹配模式提取子目录并创建符号链接

我使用 提取文件的路径find。路径命令find如下:

tmp=$(find $Some_Dir -name "*.gz")

输出是:

echo "$tmp"

/xxxx/abc/bcd/def/something/ZRT834/ZRT834_9/5678/S1_L001_R1.gz /xx/abc/bcd/def/ddd/ZRT834/ZRT834_9/5678/S2_L001_I1.gz /abc/bcd/def/ZRT834/ZRT834_9/5678/S1_L001_I2.gz /abc/bcd/def/ZRT207/ZRT207_1/5678/S1_L001_R1.gz /abc/bcd/def/hfgdh/ZRT207/ZRT207_1/5678/S1_L001_R2.gz /abc/bcd/def/ZRT207/ZRT207_1/5678/S1_L001_I2.gz /sgdj/hbsdj/ldnc/jnjdss/ZRT102_9/S5_L002_I1.gz

我想根据匹配模式创建一个子目录并创建符号链接。例如,我想匹配每个路径中以 开头ZRT和结尾的模式_somenumber,并使用该路径元素创建子目录(如果不存在)。然后将文件的符号链接创建.gz到各自的目录中。

输出需要是:带有、、等ZRT834_9符号链接的目录。S1_L001_R1.gzS2_L001_I1.gzS1_L001_I2.gz

编辑:这是我原来的问题。另外,我之前发布了一个不太复杂的问题这里

答案1

关于tmp=$(find $Some_Dir -name "*.gz")

  1. 始终引用您的 shell 变量,即"$Some_Dir",而不仅仅是$Some_Dir,请参阅https://mywiki.wooledge.org/Quotes
  2. 不要将文件名读入标量变量,因为如果这样做,处理文件名中的空格会变得更加困难,请将它们读入数组。

所以应该是:

readarray -d '' files < <(find "$Some_Dir" -type f -name '*.gz' -print0)

现在您可以循环文件来做任何您想做的事情,例如,因为您说过I want to match the pattern starting with ZRT and ending with _somenumber

re='ZRT.*_somenumber'
for file in "${files[@]}"; do
    if [[ $file =~ $re ]]; then
        do whatever you like
    fi
done

显然,您首先不需要文件数组,您可以直接在以下输出上循环find

re='ZRT.*_somenumber'
while IFS= read -r -d '' file; do
    if [[ $file =~ $re ]]; then
        do whatever you like
    fi
done < <(find "$Some_Dir" -type f -name '*.gz' -print0)

答案2

可以在查找文件的过程中立即执行此操作:

find Dir/ -name '*.gz' -regex '.*/ZRT[^/]*_[0-9]+/.*' -exec \
bash -c ': "$(grep -o "/ZRT[^/]*_[0-9]\+/" <<<"$0")";\
mkdir -p "${_#/}"; ln -s "$0" "${_#/}"' {} \;

相关内容