我使用 提取文件的路径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.gz
S2_L001_I1.gz
S1_L001_I2.gz
编辑:这是我原来的问题。另外,我之前发布了一个不太复杂的问题这里。
答案1
关于tmp=$(find $Some_Dir -name "*.gz")
:
- 始终引用您的 shell 变量,即
"$Some_Dir"
,而不仅仅是$Some_Dir
,请参阅https://mywiki.wooledge.org/Quotes。 - 不要将文件名读入标量变量,因为如果这样做,处理文件名中的空格会变得更加困难,请将它们读入数组。
所以应该是:
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" "${_#/}"' {} \;