Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash UNIX:如何搜索同名文件并将其复制到其他目录_Bash_Unix_Ssh - Fatal编程技术网

Bash UNIX:如何搜索同名文件并将其复制到其他目录

Bash UNIX:如何搜索同名文件并将其复制到其他目录,bash,unix,ssh,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

我想我会把它放在这里,以帮助任何需要它的人

我有一个名为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

一个简单的
bash
for循环
可以实现以下目标:-

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
脚本的关键部分是获取每个文件的源路径,这是我通过
readlink
dirname
实现的。请参阅他们的
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'

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

这也是正确的

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

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”
打印找到的文件的路径名,并附加一个空值

<代码> XARGS—0 可以读取所找到的文件,并将NULL CHAR视为条目之间的分隔符。

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

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

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'

请遵循本网站的格式。提出问题中的问题,然后提供以下答案。请注意,Bash
$[…算术…]
表示法已被弃用,取而代之的是
$(…算术…)
(…算术…)
-请参阅。带有单方括号的
$[…]
不再记录。目录名中的空格字符或其他特殊字符将打破此限制:
mkdir foo\bar;触摸foo\bar/speadsheet.csv
我对符号链接的特殊情况编码感到困惑。为什么有必要?当您使用
cp
访问符号链接时,它将在符号链接末尾复制文件,而不是复制符号链接信息。因此,使用
readlink
dirname
似乎有点过头了-系统将自动处理,无需任何进一步的ado(因此
cp-v“$file”“$new\u location/$fileName$COUNTER.csv”
只要将
文件名
更改为“电子表格”即可,因为数字必须在
.csv
扩展名之前)。