linux wildcard usage in cp and mv
我正在编写一个脚本来处理20个文件。 它们全部位于不同的目录中。 我有部分文件名。
File1目录为/data/data1directory/Sample_File1/logs/File1_Data_time.err
File2目录为/data/data2directory/Sample_File2/logs/File2_Data_time.err
.....
我的脚本看起来像这样。 (runrunrun.sh)
1 2 3 4 5 | #!/bin/bash INPUT=$1 mv /data/*/Sample_*/logs/*_Data_time.err /data/*/Sample_*/logs/*_Data_time_orig.err cp /data/*/Sample_*/scripts/*.sh /data/*/Sample_*/scripts/*_orig.sh sh /data/*/Sample_*/scripts/*_orig.sh |
运行时,我尝试过。
./runrunrun.sh File1
。 runrunrun.sh File1
sh runrunrun.sh File1
mv:无法移动
cp也得到了类似的反馈
我做对了吗?
谢谢!
让我们谈论通配符如何工作一分钟。
1 | cp *.txt foo |
如果存在与该glob匹配的文件,则实际上不使用参数
1 | cp a.txt b.txt c.txt foo |
同样,类似
1 | mv *.txt *.old |
...可能不知道该怎么办,因为调用它时,所看到的是:
1 | mv a.txt b.txt c.txt *.old |
或者更糟糕的是,如果您已经有一个名为
1 | mv a.txt b.txt c.txt z.old |
因此,您需要使用其他工具。考虑:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | # REPLACES: mv /data/*/Sample_*/logs/*_Data_time.err /data/*/Sample_*/logs/*_Data_time_orig.err for f in /data/*/Sample_*/logs/*_Data_time.err; do mv"$f""${f%_Data_time.err}_Data_time_orig.err" done # REPLACES: cp /data/*/Sample_*/scripts/*.sh /data/*/Sample_*/scripts/*_orig.sh for f in /data/*/Sample_*/scripts/*.sh; do cp"$f""${f%.sh}_orig.sh" done # REPLACES: sh /data/*/Sample_*/scripts/*_orig.sh for f in /data/*/Sample_*/scripts/*_orig.sh; do if [[ -e"$f" ]]; then # honor the script's shebang and let it choose an interpreter to use "$f" else # script is not executable, assume POSIX sh (not bash, ksh, etc) sh"$f" fi done |
这使用了参数扩展来去除旧名称的末尾,然后再添加新名称名称。
在想要对通配符(或更复杂的)文件名匹配执行操作的简单情况下,可以非常简洁地使用
通过让
如果我们想将当前目录中所有以" report"开头的文件移动到另一个并行目录" reports":
1 | find . -name"report*.*" -exec mv '{}' ../reports/ \; |
通配符字符串必须用引号引起来,标记"找到"的文件名的{}必须用引号引起来,并且必须转义最后的分号-所有这些都是由于对这些字符进行了Bash / shell处理。
请查看
尝试这个:
更改这些:
1 2 | zc_cd_delim_01.csv zc_cd_delim_04.csv |
这些:
1 2 | zc_cd_delim_113_01.csv zc_cd_delim_113_04.csv |
命令行:
1 2 3 | for f in zc_cd_delim_??.csv; do var1=${f%%??.*}; mv $f"${var1}113_${f#$var1}"; done |