1
  • 我有一个目录,里面有 4 个目录。
  • 我想创建第 5 个目录(cx1_date)并创建 4 个与原始目录同名的空目录
  • 然后我想将两个文件从每个原始目录复制到具有各自名称的新子目录
  • 我认为我收到了一个错误,因为它试图复制 PWD 本身(因为这显示为 find 调用的结果),所以我尝试包含一个 if 语句,但我认为它不起作用

    now=$(date +"%m_%d_%Y")
    
    PWD="/nmr/charlie"
    
    mkdir $PWD/cx1_$now
    
    for name in $(find $PWD -maxdepth 1 -type d); do
    if [[ "$name" = "$PWD" && "$PWD" = "$name" ]];
    then 
        :
    else 
        cd $PWD/cx1_$now
        mkdir $PWD/$name
        cd $PWD/$name 
        cp file1.ext $PWD/cx1_$now/$name
        cp file2.ext $PWD/cx1_$now/$name
    fi 
    done
    

错误的第一行

mkdir:无法创建目录`/nmr/charlie/cx1_05_15_2012//nmr/charlie/cx1_05_15_2012':没有这样的文件或目录

提前感谢您提供的任何帮助!

查理

4

2 回答 2

2

第二个mkdir不想要$PWD

now=$(date +"%m_%d_%Y")

DIR="/nmr/charlie"

mkdir $DIR/cx1_$now

for name in $(find $DIR -maxdepth 1 -type d)
do
    if [[ "$name" != "$DIR" ]]
    then 
        (cd $DIR/cx1_$now; mkdir $name)
        (cd $DIR/$name 
         cp file1.ext $DIR/cx1_$now/$name
         cp file2.ext $DIR/cx1_$now/$name
        )
    fi
done

另外,PWD 是一个内置变量;你不应该设置它(通过cd命令除外)。

您不需要if;中的对称测试 您可以使用!=而不是=避免空then子句(好的,它包含一个很好的止痛:命令;如果您反转测试,则不需要它)。

我通常将cd操作放入子外壳中;这样,我就不会那么困惑了。第二行的替代方法mkdir是这样,它不需要cdor 子shell:

mkdir -p $DIR/cx1_$now/$name

我建议对日期使用 ISO 8601 格式,例如:

now=$(date +"%Y_%m_%d")

这样,目录将自动按日期顺序排序。


我仍然收到错误:

mkdir: cannot create directory `/nmr/charlie/directory_name_1': File exists
/home/charlie/Desktop/scripts/test.sh: line 16: cd: /nmr/charlie//nmr/charlie/directory_name_1: No such file or directory 

问题可能意味着我们还没有正确过滤。例如,每次创建备份目录时,都会将之前的备份目录全部备份到新的目录中,这就有点过分了。所以,练习的另一部分是过滤find更好的输出。

...我们应该使用目录的基本名称,我们也可以避免所有cd操作:

now=$(date +"%m_%d_%Y")

DIR="/nmr/charlie"

mkdir $DIR/cx1_$now

for name in $(find $DIR -maxdepth 1 -type d | grep -v '/cx1_[^/]*$')
do
    if [[ "$name" != "$DIR" ]]
    then
        targetdir=$DIR/cx1_$now/$(basename $name)
        mkdir -p $targetdir
        cp $name/file1.ext $name/file2.ext $targetdir
    fi
done

您确实知道使用“sh -x script.sh”或“bash -x script.sh”来运行脚本并查看它在做什么。我什至不确定我们是否需要从列表中过滤掉任何看起来像备份目录的if条件。grep

我注意到这仅在目录路径健全且不包含空格的情况下才有效。如果您使用不可移植的文件名(仅使用可移植的名称),事情就会很快出错[-_.A-Za-z0-9]。换行符和空格真的很乱。

请注意,如果您在目录下或除其本身/nmr/backup/charlie以外的任何地方进行备份,这会更简单。/nmr/charlie然而,小心,它可以根据要求在原地完成。

于 2012-05-15T15:43:57.567 回答
2

您正在使用 $PWD,就好像它意味着“/nmr/charlie”和“/nmr/charlie/cx1_date”。它只意味着第一个。

此外,当您遍历 $PWD 中的文件夹时,它也会包含 cx1_date,因为您已经创建了它,因此您应该检查它。

而且我不建议使用 PWD 作为变量名,因为它可以用于其他用途。

[编辑] 另外, $name 获取目录的完整路径,因此您需要使用 basename 仅获取目录的名称而不获取完整路径。另外,我在 if 行中犯了一个错误,并且在第二次比较中它应该是 != 而不是 = 。对不起,我当时没有外壳来测试。下面的代码现在可以工作了,我已经测试过了。

这应该有效:

now=$(date +"%m_%d_%Y")

DIR="/nmr/charlie"

mkdir $DIR/cx1_$now

for name in $(find $DIR -maxdepth 1 -type d)
do
    if [[ "$name" != "$DIR" && "$name" != "$DIR/cx1_$now" ]];
    then 
        targetdir=$(basename $name)
        cd $DIR/cx1_$now
        mkdir $DIR/cx1_$now/$targetdir
        cd $DIR/$targetdir
        cp file1.ext $DIR/cx1_$now/$targetdir
        cp file2.ext $DIR/cx1_$now/$targetdir
    fi 
done
于 2012-05-15T15:47:10.467 回答