如何在shell中复制不以特定文件扩展名结尾的文件

时间:2011-01-03 07:55:47

标签: unix shell copy

例如,复制所有不以.txt

结尾的文件

7 个答案:

答案 0 :(得分:4)

Bash会接受一种非模式。

cp !(*.txt)

答案 1 :(得分:1)

您可以将ls与grep -v选项一起使用:

for i in `ls | grep -v ".txt"`
do
    cp $i $dest_dir
done

答案 2 :(得分:1)

根据您对文件名中的字符可以承担多少假设,它可能很简单:

cp $(ls | grep -v '\.txt$') /some/other/place

如果这对您不起作用,那么可以使用find ... -print0 | xargs -0 cp ...代替(虽然这有问题 - 因为目标位于参数列表的末尾)。

在MacOS X上,xargs有一个选项-J,支持所需内容:

  

-J replstr

     

如果指定了此选项,xargs将使用从标准输入读取的数据来替换第一次出现的replstr而不是append-                所有其他参数之后的数据。此选项不会影响从输入(-n)读取的参数数量,或者输入的大小                命令xargs将生成(-s)。该选项只会移动到那些参数将被放置在执行的命令中。该                replstr必须显示为xargs的独特参数。例如,如果它位于带引号的字符串的中间,则无法识别。                此外,只会替换第一次出现的replstr。例如,以下命令将复制文件列表和                以当前目录中以大写字母开头的目录到destdir:

/bin/ls -1d [A-Z]* | xargs -J % cp -rp % destdir

GNU xargs似乎没有-J,但确实有相关但略有限制性的-I选项(MacOS X中也存在):

  

-I replace-str

     

用initial替换initial-arguments中出现的replace-str             从标准输入读取的名称。此外,不带引号的空白不会             终止输入项目;相反,分隔符是换行符             字符。意味着-x和-L 1。

答案 3 :(得分:1)

你可以信赖:

find . -not -name "*.txt"

使用:

find -x . -not -name "*.txt" -d 1 -exec cp '{}' toto/ \;`

将当前目录中不是.txt的所有文件复制到子目录toto /。 -d 1用于防止递归。

答案 4 :(得分:1)

要么:

for f in $(ls | grep -v "\.txt$")
do
  cp -- "$f" ⟨destination-directory⟩
done

或者如果您有大量文件:

find -prune \! -name "*.txt" -exec cp -- "{}" ⟨destination-directory⟩ .. \;

这里有两件事要评论。一个是在调用 cp,和引用$f时使用双连字符。第一个防止以“连字符”开头的“古怪”文件名可能会被解释为选项。第二名警卫再次使用空格(或IFS中的内容)文件名。

答案 5 :(得分:0)

我会这样做,其中 destination 是目标目录:

ls | grep -v "\.txt$" | xargs cp -t destination

修改:由于评论

,添加了“-t”

答案 6 :(得分:0)

zsh

setopt extendedglob
cp *^.txt /some/folder

(如果你只想要文件)......

cp *.^txt(.) /some/folder

有关zsh globbing herehere的更多信息。