cp和mv中的linux通配符使用
Posted
技术标签:
【中文标题】cp和mv中的linux通配符使用【英文标题】:linux wildcard usage in cp and mv 【发布时间】:2016-06-13 00:29:48 【问题描述】:我正在编写一个脚本来处理 20 个文件。它们都位于不同的目录中。我有部分文件名。
-
在日志目录中,File1_Date_time.err 更改为 File1__Date_time_orig.err
cd ../scripts/
sh 文件.sh
File1 目录为 /data/data1directory/Sample_File1/logs/File1_Data_time.err File2目录为/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 文件1 . runrunrun.sh 文件 1 sh runrunrun.sh 文件1
mv: 无法移动 /data/data1directory/Sample_File1/logs/File1_Data_time.err /data/*/Sample_*/logs/*_Data_time_orig.err
: 没有这样的文件或目录
cp也得到了类似的反馈
我做得对吗?
谢谢!
【问题讨论】:
mv
、cp
等没有通过您正在编写的通配符,如果这些通配符有任何有效的扩展。相反,它们被传递通过运行这些扩展创建的文字文件名。因此,由于他们不知道输入名称中使用的文字通配符,因此他们不可能将输入名称中的 *
映射到输出名称中的 *
。
如果你想编写重命名工具,BashFAQ #30 是一个不错的起点:mywiki.wooledge.org/BashFAQ/030
相关:***.com/questions/20629302/…
顺便说一句,sh foo.sh
非常危险,除非您绝对确定该脚本以 #!/bin/sh
而不是 #!/bin/bash
、#!/bin/ksh
、@987654333 开头@, 等等;否则,它可能会使用错误的解释器。
【参考方案1】:
使用 awk 和 sed
使用 ls 过滤,使用 awk 为每条记录构建移动命令,最后的 sed 'e' 将执行该命令。
ls *.avro | awk ' print "mv "$1" aa_"$1 ' | sed 'e'
首先尝试不使用 sed -- 一旦您知道您的命令显示正确,请添加 sed。
【讨论】:
【参考方案2】:find
命令可以非常简洁地用于您想要对通配符(或更复杂的)文件名匹配执行操作的简单情况。下面的技术可以提交到内存中......几乎!
这通过让find
命令在它找到的每个文件名上运行另一个命令来工作。您可以使用echo
代替/在mv
前面来试运行此示例。
如果我们想将当前目录中名称以“report”开头的所有文件移动到另一个名为“reports”的并行目录:
find . -name "report*.*" -exec mv '' ../reports/ \;
通配符字符串必须用引号括起来,标记“找到”的文件名的 必须用引号括起来,最后的分号必须被转义 - 所有这些都是由于对这些字符的 Bash/shell 处理。
查看find
的手册页以了解更多用途:https://linux.die.net/man/1/find
【讨论】:
如果多个文件的文件名相同,这个解决方案似乎会覆盖目标中的文件。如何复制整个文件夹结构? 第一个答案涵盖了我的情况。我还使用 cp --parents ============================= for f in ./*/*20220202.csv;做 cp -rfv --parents "$f" "/projects/drprojects/evmc/tempo4/" 完成 代码只是一个例子。原来的问题也有这个问题。问一个单独的问题,或者解决它!【参考方案3】:这是我用的,写起来很快,记起来也很快
复制:
ls -1 *.txt | xargs -L1 -I cp .old
搬家:
ls -1 *.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
使 成为占位符
【讨论】:
带有有趣文件名的越野车。一般来说, xargs 只有在 NUL 分隔的输入和-0
参数下才是安全的;默认行为将输入拆分为空格,而不仅仅是换行符(尽管换行符也不安全,因为它们在文件名中是允许的);将引号字符视为语法而不是文字数据;否则通常会输入。
另见Why you shouldn't parse the output of ls
【参考方案4】:
让我们来谈谈通配符的工作原理。
cp *.txt foo
如果存在与该 glob 匹配的任何文件,则实际上不会使用参数 *.txt
调用 cp
。相反,它运行如下:
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 在添加新名称之前去除旧名称的尾部。
【讨论】:
从 2020 年开始,GNU bash 5.0 及更高版本不再是这种情况 @user164863,请提供相反的演示。mv
和 cp
不是 bash 本身的一部分,它们由您的操作系统供应商提供,并且 glob 在调用之前已经扩展;这些都没有改变。【参考方案5】:
试试这个:
改变这些:
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 "$var1113_$f#$var1";
done
【讨论】:
mv "$f"
,而是 -- 如果??
匹配带有空格的文件名,或者IFS
包含在名称中找到的字符(即_
),否则行为可能会令人惊讶.
顺便说一句,我有点不清楚这如何适用于手头的问题——c_cd_delim_??.csv
在我看来并不像 OP 用作示例的模式之一他们想要匹配的东西。您介意编辑以使问题的适用性更清晰吗?以上是关于cp和mv中的linux通配符使用的主要内容,如果未能解决你的问题,请参考以下文章