cp和mv中的linux通配符用法

TJ *_* Wu 7 linux shell mv cp

我正在编写一个脚本来处理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.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
Run Code Online (Sandbox Code Playgroud)

在运行时,我试过了.
./runrunrun.sh File1
.runrunrun.sh File1
sh runrunrun.sh File1

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

我做得对吗?

谢谢!

Mik*_*keW 23

find在您想要对通配符(或更复杂)文件名匹配执行操作的简单情况下,可以非常简洁地使用该命令。下面的技术可以提交到内存......几乎!

这是通过让find命令在它找到的每个文件名上运行另一个命令来实现的。您可以使用echo代替/在mv.

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

find . -name "report*.*" -exec mv '{}' ../reports/ \;
Run Code Online (Sandbox Code Playgroud)

通配符字符串必须用引号括起来,标记“找到”的文件名的 {} 必须用引号括起来,最后的分号必须转义——所有这些都是由于 Bash/shell 对这些字符的处理。

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


Cha*_*ffy 12

我们来谈谈通配符如何工作一分钟.

cp *.txt foo
Run Code Online (Sandbox Code Playgroud)

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

cp a.txt b.txt c.txt foo
Run Code Online (Sandbox Code Playgroud)

同样,像

mv *.txt *.old
Run Code Online (Sandbox Code Playgroud)

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

mv a.txt b.txt c.txt *.old
Run Code Online (Sandbox Code Playgroud)

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

mv a.txt b.txt c.txt z.old
Run Code Online (Sandbox Code Playgroud)

因此,您需要使用不同的工具.考虑:

# 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
Run Code Online (Sandbox Code Playgroud)

这使用参数扩展来在添加新名称之前去除旧名称的尾部.

  • @user164863,请提供相反的证明。`mv` 和 `cp` 不是 bash 本身的一部分,它们由操作系统供应商提供,并且 glob 在调用之前已经扩展;这些都没有改变。 (2认同)

Edu*_*scu 7

这就是我用的,写起来和记住都很快

用于复印:

ls -1 *.txt | xargs -L1 -I{} cp {} {}.old 
Run Code Online (Sandbox Code Playgroud)

对于移动:

ls -1 *.txt | xargs -L1 -I{} mv {} {}.old 
Run Code Online (Sandbox Code Playgroud)

说明:

xargs(1) -L1 -I{}  
Run Code Online (Sandbox Code Playgroud)

从标准输入构建并执行命令行

-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.
Run Code Online (Sandbox Code Playgroud)

基本上用-L1它发送参数加一,-I{}并使{}占位

  • 带有有趣文件名的 Buggy。一般来说,xargs 仅对于 NUL 分隔的输入和“-0”参数是安全的;默认行为在空格上分割输入,而不仅仅是换行符(尽管换行符也不安全,因为它们在文件名中是允许的);将引号字符视为语法而不是文字数据;否则一般都会输入 munges。 (2认同)