Я сделал этот простой скрипт для рекурсивного копирования файла во многие подкаталоги. Здесь я показываю проблему для 3 подкаталогов. У меня есть 3 подкаталога и 2 файла в каталоге следующим образом
0.003/ 0.007/ 0.015/ program.cpp driver.sh*
Я хочу скопировать program.cpp
во все эти подкаталоги, используя myscript.sh
, показанный ниже:
#!/bin/bash
mydir=`pwd`
for i in `ls -la $mydir | grep "[0-9]$" | awk '{print $NF}'`
do
if [ -e $mydir/$1 ]
then
echo "cp -i $1 $i/"
else
echo "File \"$1\" not found in current directory"
fi
done
Я поместил cp
внутрь echo
, чтобы проверить код. Вывод странный,
cp -i program.cpp 32/
cp -i program.cpp 0.003/
cp -i program.cpp 0.007/
cp -i program.cpp 0.015/
Выход ls -la
total 32K
drwxr-xr-x. 5 gulu workg 4.0K Nov 29 2013 .
drwxr-xr-x. 7 gulu workg 4.0K Nov 29 2013 ..
drwxr-xr-x. 2 gulu workg 4.0K Nov 26 19:09 0.003
drwxr-xr-x. 2 gulu workg 4.0K Nov 26 19:09 0.007
drwxr-xr-x. 2 gulu workg 4.0K Nov 26 19:09 0.015
-rw-r--r--. 1 gulu workg 4.2K Nov 29 2013 program.cpp
-rwxr-xr-x. 1 gulu workg 982 Nov 26 08:22 driver.sh
Выход ls -la $mydir | grep "[0-9]$" | awk '{print $NF}'
0.003
0.007
0.015
Есть только три значения в i
Тогда как получается четыре выхода? Во всяком случае, я решил проблему с дополнительным условием [ -d $mydir/$i ]
. Но мой вопрос в том, как скрипт выдает первую строку cp -i driver.sh 32/
?
Это иллюстрирует, почему вы НИКОГДА не должны полагаться на синтаксический анализ выходных данных команды ls
для перебора содержимого каталога - вместо этого используйте простой глобус оболочки, например, чтобы соответствовать любому имени файла, оканчивающемуся на цифру
for f in $mydir/*[0-9]
do
if [ -e $mydir/$1 ]
.
.
done
Относительно того, как оно производит строку cp -i driver.sh 32/
, вы можете видеть, что когда вы выбираете цифры в выводе ls -la
, это соответствует total: 32K
строка, а также нужные имена каталогов.
Это иллюстрирует, почему вы НИКОГДА не должны полагаться на анализ выходных данных команды ls для перебора содержимого каталога - используйте простую команду find
:
find . -maxdepth 1 -type d --regex './[0-9]+ -exec cp $1 {} \;