cp和mv中的Linux通配符用法

问题描述 投票:9回答:4

我正在编写一个脚本来处理20个文件。它们全部位于不同的目录中。我有部分文件名。

  1. 在日志目录中,File1_Date_time.err更改为File1__Date_time_orig.err
  2. cd ../scripts/
  3. sh File.sh

File1目录是/data/data1directory/Sample_File1/logs/File1_Data_time.errFile2目录为/data/data2directory/Sample_File2/logs/File2_Data_time.err.....

我的脚本看起来像这样。 (runrunrun.sh)

#!/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 File1sh runrunrun.sh File1

mv:不能移动/data/data1directory/Sample_File1/logs/File1_Data_time.err /data/*/Sample_*/logs/*_Data_time_orig.err:没有这样的文件或目录cp也得到了类似的反馈

我做对了吗?

谢谢!

linux shell cp mv
4个回答
14
投票

让我们讨论通配符如何工作一分钟。

cp *.txt foo

如果存在与该glob匹配的文件,则实际上不使用参数cp调用*.txt。相反,它运行如下所示:

cp a.txt b.txt c.txt foo

类似地,类似

mv *.txt *.old

...可能不知道该怎么办,因为当它被调用时,所看到的是:

mv a.txt b.txt c.txt *.old

或更糟糕的是,如果您已经[[拥有一个名为z.old的文件,它将看到:

mv a.txt b.txt c.txt z.old

因此,您需要使用其他工具。考虑:

# 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

这会在添加新名称之前使用parameter expansion去除旧名称的尾端。

5
投票
find命令在要对通配符(或更复杂)的文件名匹配执行操作的简单情况下可以非常简洁地使用。以下技术可以用于内存...几乎!

这通过让find命令在找到的每个文件名上运行另一个命令来工作。您可以使用echo而不是mv来空运行此示例。

如果我们想将当前目录中所有以'report'开头的文件移动到另一个名为'reports'的并行目录:

find . -name "report*.*" -exec mv '{}' ../reports/ \;

通配符字符串必须用引号引起来,{}标记已找到的文件名必须用引号引起来,并且必须转义最后的分号-所有这些都是由于对这些字符进行了Bash / shell处理。

查看find的手册页以了解更多用途:https://linux.die.net/man/1/find


0
投票
尝试一下:

更改这些:

zc_cd_delim_01.csv zc_cd_delim_04.csv

进入这些:

zc_cd_delim_113_01.csv zc_cd_delim_113_04.csv

命令行:

for f in zc_cd_delim_??.csv; do var1=${f%%??.*}; mv $f "${var1}113_${f#$var1}"; done


0
投票
这是我使用的,非常容易写和记住

用于复制:

ls *.txt | xargs -L1 -I{} cp {} {}.old

用于移动:

ls *.txt | xargs -L1 -I{} mv {} {}.old

说明:

xargs(1) -L1 -I{}

从标准输入生成并执行命令行

-L max-lines Use at most max-lines nonblank input lines per command line. Trailing blanks cause an input line to be logically continued on the next input line. Implies -x. -I replace-str Replace occurrences of replace-str in the initial-arguments with names read from standard input. Also, unquoted blanks do not terminate input items; instead the separator is the newline character. Implies -x and -L 1.

基本上与-L1一起发送参数,而-I{}使{}成为

占位符

© www.soinside.com 2019 - 2024. All rights reserved.