我正在解析 `ls` 的输出,但出了点问题

我正在解析 `ls` 的输出,但出了点问题

我编写了这个简单的脚本,以递归方式将文件复制到多个子目录。这里我展示了 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/

答案1

这说明了为什么你永远不应该依赖解析命令的输出ls来迭代目录内容 - 而是使用简单的 shell glob,例如匹配以数字结尾的任何文件名

for f in $mydir/*[0-9]
do
    if [ -e $mydir/$1 ]
    .
    .
done

至于它是如何生成行的cp -i driver.sh 32/,您可以看到,当您在的输出中 grep 数字时ls -la,它匹配该total: 32K行以及所需的目录名称。

答案2

这说明了为什么你永远不应该依赖解析 ls 命令的输出来迭代目录内容 - 使用一个简单的find命令:

find . -maxdepth 1 -type d --regex './[0-9]+$' -exec cp $1 {} \;

相关内容