简体   繁体   English

cp 和 mv 中的 linux 通配符用法

[英]linux wildcard usage in cp and mv

I am composing a script to process 20 files.我正在编写一个脚本来处理 20 个文件。 All of them located in different directories.它们都位于不同的目录中。 I have partial file name.我有部分文件名。

  1. In log directory, File1_Date_time.err change to File1__Date_time_orig.err在日志目录中,File1_Date_time.err 更改为 File1__Date_time_orig.err
  2. cd../scripts/ cd../脚本/
  3. sh File.sh sh文件.sh

File1 directory is /data/data1directory/Sample_File1/logs/File1_Data_time.err File1目录是/data/data1directory/Sample_File1/logs/File1_Data_time.err
File2 directory is /data/data2directory/Sample_File2/logs/File2_Data_time.err File2目录是/data/data2directory/Sample_File2/logs/File2_Data_time.err
..... .....

My script looks like this.我的脚本看起来像这样。 (runrunrun.sh) (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

When running it, I tried.运行它时,我试过了。
./runrunrun.sh File1 ./runrunrun.sh 文件1
. . runrunrun.sh File1 runrunrun.sh 文件1
sh runrunrun.sh File1 sh runrunrun.sh File1

mv: cannot move /data/data1directory/Sample_File1/logs/File1_Data_time.err /data/*/Sample_*/logs/*_Data_time_orig.err : No such file or directory cp also got similar feedback mv: cannot move /data/data1directory/Sample_File1/logs/File1_Data_time.err /data/*/Sample_*/logs/*_Data_time_orig.err : No such file or directory cp 也得到了类似的反馈

Am I doing it correct?我做的对吗?

Thanks!谢谢!

Let's talk about how wildcards work for a minute.让我们先谈谈通配符的工作原理。

cp *.txt foo

doesn't actually invoke cp with an argument *.txt , if any files matching that glob exist.如果存在与该 glob 匹配的任何文件,则实际上不会使用参数*.txt调用cp Instead, it runs something like this:相反,它运行如下:

cp a.txt b.txt c.txt foo

Similarly, something like同样,类似的东西

mv *.txt *.old

...can't possibly know what to do, because when it's invoked, what it sees is: ...不可能知道该怎么做,因为当它被调用时,它看到的是:

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

or, worse, if you already have a file named z.old , it'll see:或者,更糟糕的是,如果您已经一个名为z.old的文件,它会看到:

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

Thus, you need to use different tools.因此,您需要使用不同的工具。 Consider:考虑:

# 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

This uses a parameter expansion to strip off the tail end of the old name before adding the new name.这使用参数扩展在添加新名称之前去除旧名称的尾端。

The find command can be used quite concisely in simple cases where you want to perform operations on wildcard (or more complex) filename matches.在您想要对通配符(或更复杂)文件名匹配执行操作的简单情况下,可以非常简洁地使用find命令。 The technique below can be committed to memory ... almost !下面的技术可以提交到内存......几乎!

This works by letting the find command run another command on each filename it finds.这是通过让find命令在它找到的每个文件名上运行另一个命令来实现的。 You can dry-run this example using echo instead of/in front of mv .您可以使用echo而不是 / 在mv前面空运行此示例。

If we wanted to move all files in the current directory with name beginning 'report', to another parallel directory called 'reports' :如果我们想将当前目录中名称以“report”开头的所有文件移动到另一个名为“reports”的并行目录中:

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

The wildcard string must be in quotes, the {} marking the filename that was 'found' must be in quotes, and the final semicolon must be escaped - all due to Bash/shell treatment of those characters.通配符字符串必须用引号括起来,标记“找到”的文件名的 {} 必须用引号括起来,最后的分号必须转义 - 所有这些都是由于 Bash/shell 对这些字符的处理。

Look at the man page for find for more uses: https://linux.die.net/man/1/find看看man页面find更多的用途: https://linux.die.net/man/1/find

This is what I use, very fast to write and remember这是我用的,写起来很快,记起来也很快

For copying:对于复制:

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

For moving:搬家:

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

the explanation:说明:

xargs(1) -L1 -I{}  

build and execute command lines from standard input从标准输入构建和执行命令行

-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.

Basically with -L1 it sends the arguments on by one, and -I{} makes {} the placeholder基本上使用-L1它将参数-L1发送,而-I{}使{}成为占位符

using awk and sed使用 awk 和 sed

Filter using ls, use awk to build your move command for each record and the sed 'e' in the end will execute the command.使用 ls 过滤,使用 awk 为每条记录构建移动命令,最后的 sed 'e' 将执行该命令。

ls  *.avro  | awk ' { print "mv "$1" aa_"$1 }' | sed 'e'

First try without the sed -- once you know your command is showing correctly add the sed.首先尝试不使用 sed - 一旦您知道您的命令显示正确,请添加 sed。

Try this:尝试这个:

Change these:改变这些:

zc_cd_delim_01.csv
zc_cd_delim_04.csv

into these:进入这些:

zc_cd_delim_113_01.csv
zc_cd_delim_113_04.csv

command line:命令行:

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

I am composing a script to process 20 files.我正在编写一个脚本来处理20个文件。 All of them located in different directories.它们全部位于不同的目录中。 I have partial file name.我有部分文件名。

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

File1 directory is /data/data1directory/Sample_File1/logs/File1_Data_time.err File1目录为/data/data1directory/Sample_File1/logs/File1_Data_time.err
File2 directory is /data/data2directory/Sample_File2/logs/File2_Data_time.err File2目录为/data/data2directory/Sample_File2/logs/File2_Data_time.err
..... .....

My script looks like this.我的脚本看起来像这样。 (runrunrun.sh) (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

When running it, I tried.运行时,我尝试过。
./runrunrun.sh File1 ./runrunrun.sh File1
. runrunrun.sh File1 runrunrun.sh File1
sh runrunrun.sh File1 sh runrunrun.sh File1

mv: cannot move /data/data1directory/Sample_File1/logs/File1_Data_time.err /data/*/Sample_*/logs/*_Data_time_orig.err : No such file or directory cp also got similar feedback mv:无法移动/data/data1directory/Sample_File1/logs/File1_Data_time.err /data/*/Sample_*/logs/*_Data_time_orig.err :此类文件或目录cp也没有得到类似的反馈

Am I doing it correct?我做对了吗?

Thanks!谢谢!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM