UNIX:如何搜索具有相同名称的所有文件并将其复制到其他目录

时间:2016-05-24 16:09:48

标签: bash unix ssh

我想我会把它放在这里帮助其他可能需要它的人。

我有一个名为spreadsheet.csv的文件,它位于我服务器上的500个不同位置。经过一系列的试验和错误后,我确定了这个解决方案,复制了这个文件的每个实例,重命名它(按增量)并将其复制到另一个文件夹中。

希望这有助于某人!

COUNTER=0; 
for f in $(find folder/ -name 'spreadsheet.csv'); 
do 
  cp -v $f /new/location/spreadsheet$COUNTER.csv; 
  COUNTER=$[$COUNTER+1]; 
done

2 个答案:

答案 0 :(得分:1)

简单的bash for-loop可以实现这一目标: -

COUNTER="0"
fileName="spreadsheet.csv"
for file in $(find folder/ -name "$fileName" -type f -printf '%P\n'); 
do
  sourcePath=$(dirname $(readlink -f "$file")) 
  cp -v $sourcePath/$fileName /new/location/"$fileName$COUNTER" 
  COUNTER=$((COUNTER+1)) 
done

脚本的关键部分是获取每个文件的源路径,我通过readlinkdirname实现了这些路径。请参阅他们的man页面以了解有关其说明的更多信息。

实施例: -

$ find . -name "spreadsheet.csv" -type f
./foo/spreadsheet.csv
./bar/spreadsheet.csv
./woo/spreadsheet.csv
./spreadsheet.csv

 $ ./script.sh
`/home/dude/foo/spreadsheet.csv' -> `/new/location/spreadsheet.csv0'
`/home/dude/bar/spreadsheet.csv' -> `/new/location/spreadsheet.csv1'
`/home/dude/woo/spreadsheet.csv' -> `/new/location/spreadsheet.csv2'
`/home/dude/spreadsheet.csv' -> `/new/location/spreadsheet.csv3'

答案 1 :(得分:0)

如果至少有一个目录名中有空格或特殊字符,则脚本将中断。

Iniansymlinks也是正确的。

以下是一个安全且标准的解决方案,只搜索常规文件:

find folder/ -type f -name 'spreadsheet.csv' -printf "%p\0" | xargs -0 sh -c '
  newlocdir=/new/location;
  COUNTER=$(ls -1 "${newlocdir}"/spreadsheet*.csv 2>/dev/null | awk "END {print NR}") ;
  for f ; do
    cp -v "${f}" "${newlocdir}"/spreadsheet$COUNTER.csv;
    COUNTER=$(($COUNTER+1));
  done' dummyarg0

-printf "%p\0"打印带有附加NULL的文件的路径名。

xargs -0能够读取找到的文件,并将NULL char视为条目之间的分隔符。

| awk "END {print NR}"打印从管道读取的行数。

COUNTER=$(ls -1 "${newlocdir}"/spreadsheet*.csv 2>/dev/null | awk "END {print NR}")将已存在于新位置的spreadsheet*.csv个文件的数量存储到COUNTER变量中。

for f ; do读取位置参数; xargs提供的文件名。

sh -c ' .... ' dummyarg0 make sh执行提供的命令。 dummyarg0是必需的第一个参数。 sh将特殊参数0的值设置为dummyarg0(未使用)。

测试:

$ find folder/
folder/
folder/dir2
folder/dir2/spreadsheet.csv
folder/foo bar
folder/foo bar/spreadsheet.csv
folder/spreadsheet.csv
folder/tr"uc
folder/tr"uc/spreadsheet.csv
folder/fo'o
folder/fo'o/spreadsheet.csv
folder/dir1
folder/dir1/spreadsheet.csv
$ find folder/ -type f -name 'spreadsheet.csv' -printf "%p\0" | xargs -0 sh -c '
  newlocdir=.;
  COUNTER=$(ls -1 "${newlocdir}"/spreadsheet*.csv 2>/dev/null | awk "END {print NR}") ;
  for f ; do
    cp -v "${f}" "${newlocdir}"/spreadsheet$COUNTER.csv;
    COUNTER=$(($COUNTER+1));
  done' dummyarg0
`folder/dir2/spreadsheet.csv' -> `./spreadsheet0.csv'
`folder/foo bar/spreadsheet.csv' -> `./spreadsheet1.csv'
`folder/spreadsheet.csv' -> `./spreadsheet2.csv'
`folder/tr"uc/spreadsheet.csv' -> `./spreadsheet3.csv'
`folder/fo\'o/spreadsheet.csv' -> `./spreadsheet4.csv'
`folder/dir1/spreadsheet.csv' -> `./spreadsheet5.csv'