提取子字符串,直到并使用 bash 工具包含匹配的单词



我有这样的文件名:

func/sub-01_task-biommtloc_run-01_bold_space-T1w_preproc.nii.gz
func/sub-01_task-pfobloc_run-01_bold_space-T1w_preproc.nii.gz
func/sub-01_task-rest_run-01_bold_space-T1w_preproc.nii.gz

从每个文件名中,我想提取部分,直到并包括单词bold,以便最终我有:

func/sub-01_task-biommtloc_run-01_bold
func/sub-01_task-pfobloc_run-01_bold
func/sub-01_task-rest_run-01_bold

有什么想法吗?

最简单的方法是删除bold和之后的所有内容,然后替换bold。显然,这仅在终止字符串固定时才有效,如本例所示。

$ f=func/sub-01_task-biommtloc_run-01_bold_space-T1w_preproc.nii.gz
$ echo "${f%%bold*}"
func/sub-01_task-biommtloc_run-01_
$ echo "${f%%bold*}bold"
func/sub-01_task-biommtloc_run-01_bold

这样的东西是你想要的吗?

echo func/sub-01_task-biommtloc_run-01_bold_space-T1w_preproc.nii.gz | sed -e 's#bold_.*$#bold#'

希望这有帮助

这是(不必要的(聪明的:删除以"粗体"结尾的前缀然后根据剩余的后缀的长度进行一些子字符串索引算术:

$ file=func/sub-01_task-biommtloc_run-01_bold_space-T1w_preproc.nii.gz
$ tmp=${file#*bold}
$ keep=${file:0:${#file}-${#tmp}}
$ echo "$keep"
func/sub-01_task-biommtloc_run-01_bold

如果$file不包含 "bold",那么$keep将为空:如果它为空,我们可以给它 $file 的值:

$ file=foobar
$ tmp=${file#*bold}
$ keep=${file:0:${#file}-${#tmp}}
$ : ${keep:=$file}
$ echo "$keep"
foobar

但说真的,按照切普纳的建议去做。

使用 Perl

> echo "func/sub-01_task-biommtloc_run-01_bold_space-T1w_preproc.nii.gz" | perl -e 'while (<>) { $_=~s/(.*bold)(.*)/1/g; print } '
func/sub-01_task-biommtloc_run-01_bold
>

这类似于 glenn 的解决方案,但有点"不那么聪明",因为它不使用子字符串,只使用嵌套替换:

$ while IFS= read -r fname; do echo "${fname%"${fname#*bold}"}"; done < infile
func/sub-01_task-biommtloc_run-01_bold
func/sub-01_task-pfobloc_run-01_bold
func/sub-01_task-rest_run-01_bold

替换"${fname%"${fname#*bold}"}"说:

  • 从每个文件名的末尾删除"${fname#*bold}",其中
  • "${fname#*bold}"是所有内容,包括从文件名前面删除bold

具有显式中间步骤的第一个文件名的示例:

$ fname=func/sub-01_task-biommtloc_run-01_bold_space-T1w_preproc.nii.gz
$ echo "${fname#*bold}"
_space-T1w_preproc.nii.gz
$ echo "${fname%"${fname#*bold}"}"
func/sub-01_task-biommtloc_run-01_bold
f=func/sub-01_task-biommtloc_run-01_bold_space-T1w_preproc.nii.g
echo "${f//bold*/bold}"

我建议使用sed来完成此任务。首先获取所有输入文件名并将它们粘贴到一个文件中,在当前目录中namelist.txt调用它。只要您的sed支持扩展正则表达式(大多数都支持扩展正则表达式,尤其是 GNU sed(,以下内容就可以了。请注意,扩展正则表达式的标志在不同平台之间可能略有不同,请查看sed手册页。在我的Linux上,它是-r.

bash -c "sed -r 's/(sub-01_task-.{1,10}_run-01_bold).+/\1/' namelist.txt"

最新更新