![](/img/trans.png)
[英]How to get single quotation marks of a command treated as normal quotation marks on (bash) shell script? (trouble with dcm2niix)
[英]How to fix shell script that works at the command line? Script uses `mv`, quotation marks, parameter expansion, and variables
我在一个目录中有一组文件。 一些文件名包含八位数的日期,如下所示:
test_file_20220101.txt
...
test_file_20220110.txt
我想使用 shell 脚本来重命名它们,使日期带有破折号,如下所示:
test_file_2022-01-01.txt
...
test_file_2022-01-10.txt
我有一些 shell 代码(大部分)在命令行上运行良好(一旦echo
被删除*):
for f in ./*;
do suffix="${f##*[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]}";
number="${f%"$suffix"}";
number="${number##*[\!0-9]}";
year="${number:0:4}";
month="${number:4:2}";
day="${number:6:2}";
echo mv "$f" "${f/$number/$year-$month-$day}";
done
但是,当我在开头添加#!/bin/sh
、 #!/bin/bash
或#!/bin/zsh
时,将其保存为脚本(具有执行权限)并运行脚本,它不会影响文件名更改,我在stdout
得到这个:
echo mv ./test_file_20220110 ./test_file_20220110
* 移除回声没有任何改变; 不希望的结果与 shell 脚本相同。 我不相信回声是问题所在。
我也尝试过,但没有成功:用 ' 替换所有'
或用'
”
删除所有引号”
所有组合都会产生相同的错误脚本输出。 添加set -v
运行脚本的输出对我没有帮助,但它是:
+ for f in './*'
+ suffix=
+ number=./test_file_20220101
+ number=
+ year=
+ month=
+ day=
+ echo mv ./test_file_20220101 ./test_file_20220101
mv ./test_file_20220101 ./test_file_20220101
... [etc.]
配置:
zsh
另外,作为一项额外的改进,我想解决一个事实,即一些没有预期的八位数模式的文件最终被重命名为--other_filename.txt
类的东西。 在 CLI 中使用上述命令后,我单独使用以下命令来成功修复此问题。
for f in *; do echo mv -- "$f" "${f##--}"; done
如果这个“cleanup”命令可以与上一次“cleanup”扫描在同一个脚本中,那就太好了。
set -v
输出可能对您没有帮助,但它告诉我脚本在尝试从文件名中提取数字时会横向移动。 至少在 bash 中,那是因为您引用了!
在你的括号表达式中。 也就是说, [\!0-9]
匹配集合 '!'、'0'、'1'、...'9' 中的一个字符,这不是您想要的。
您应该在命令行中遵守相同的规定,如果您不这样做,那么我无法解释。
您脚本的这种变化对我有用:
#!/bin/bash
for f in ./*; do
suffix=${f##*[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]}
number=${f%"$suffix"}
number=${number##*[!0-9]}
year=${number:0:4}
month=${number:4:2}
day=${number:6:2}
echo mv "$f" "${f/${number}/${year}-${month}-${day}}"
done
(除了对括号表达式的更正之外的更改是风格上的,而不是功能性的。)
这个Shellcheck -clean 代码演示了另一种方法:
#! /bin/bash -p
date_rx='([[:digit:]][[:digit:]][[:digit:]][[:digit:]])([[:digit:]][[:digit:]])([[:digit:]][[:digit:]])'
date_file_rx="(.*)${date_rx}(.*)"
for file in *; do
if [[ $file =~ $date_file_rx ]]; then
prefix=${BASH_REMATCH[1]}
year=${BASH_REMATCH[2]}
month=${BASH_REMATCH[3]}
day=${BASH_REMATCH[4]}
suffix=${BASH_REMATCH[5]}
echo mv -n -v -- "$file" "${prefix}${year}-${month}-${day}${suffix}"
fi
done
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.