我需要使用以下模式重命名一堆文件:
sub-2795479_ses-V1_task-rest_acq-REST1_dir-AP_run-01_run-01_run-01_run-01_run-01_run-01_run-01_run-01_run-01_run-01_run-01_run-01_run-01_run-01_run-01_run-01_run-01_bold.json
到
sub-2795479_ses-V1_task-rest_acq-REST1_dir-AP_run-01_bold.json
每个文件名仅包含 4 种可能性中的一种类型的子字符串 - run-01_
(或run-02_
, run-03_
, run-04
)
请注意,子字符串run-0[1-4]_
可以在给定文件中随机重复多次。
我失去了理智,我能找到的最接近的东西是Stack Overflow 上的这个问题。但是,基于我对字符串操作的有限知识,我希望获得更多帮助!
答案1
或者perl:
$ f=sub-2795479_ses-V1_task-rest_acq-REST1_dir-AP_run-01_run-01_run-01_run-01_run-01_run-01_run-01_run-01_run-01_run-01_run-01_run-01_run-01_run-01_run-01_run-01_run-01_bold.json
$ g=$(perl -pe 's/(_run-0[1-4])\1+/$1/' <<< "$f")
$ echo "$g"
sub-2795479_ses-V1_task-rest_acq-REST1_dir-AP_run-01_bold.json
使用 perl 风格的rename(1)
程序:
$ touch "$f"
$ ls sub*json
sub-2795479_ses-V1_task-rest_acq-REST1_dir-AP_run-01_run-01_run-01_run-01_run-01_run-01_run-01_run-01_run-01_run-01_run-01_run-01_run-01_run-01_run-01_run-01_run-01_bold.json
$ rename 's/(_run-0[1-4])\1+/$1/' sub*json
$ ls sub*json
sub-2795479_ses-V1_task-rest_acq-REST1_dir-AP_run-01_bold.json
答案2
使用参数扩展:
for i in *.json; do
a="${i##*_run}"
b="${i%%_run*}"
n="$b""_run$a"
# mv -- "$i" "$n"
printf "%s" "$n"
done
sub-2795479_ses-V1_task-rest_acq-REST1_dir-AP_run-01_bold.json
然后重命名:
mv -- "$i" "$n"
注意:执行删除/移动操作时请备份文件。
答案3
如果事情变得比rename
直接处理更复杂,我倾向于只编写一个具有基本相同模式的简短脚本
for file in *.json
do
changedname="$(echo "$file" | sed 's/regex/replacement/flags')"
mv -- "$file" "$changedname"
done
在您的情况下,您正在寻找 string run-0[1-4]_
,并将其替换为空字符串 `` ,并且您的标志将包括g
“执行此操作多次,直到到达行尾”,所以
sed 's/run-0[1-4]_//g'
就是你的目标。
如果不删除第一个出现的地方,那也不难!
sed -e 's/\(run-0[1-4]_.*\)run-0[1-4]_/\1/g'