Ubuntu的/ Linux的庆典:遍历目录和子目录进行文件操作(ubuntu/linux bash

2019-10-28 19:46发布

让我开始了与我所需要的; 该程序被赋予一个目录,它将然后检查目录(作品)的所有文件和做的东西到文件(等待,直到它可以找到这部分的所有文件)。 然后它会寻找子目录,然后重新运行其每个子目录的自我。

我与这个样子的测试目录:

desktop/test_files/ (starting directory)
desktop/test_files/folder 1/
desktop/test_files/folder 1>folder 2/
desktop/test_files/folder 1>folder 2/<files, 20 or so>
desktop/test_files/folder 3/
desktop/test_files/folder 3/<more files, 20 or so>

文件夹和文件确实包含在名称中使用空格

输出是:

$ ./x007_shorter.sh Desktop/test_files/

Desktop/test_files/"folder 1"/
Desktop/test_files/folder 1/"folder 2"/
ls: cannot access */: No such file or directory
Desktop/test_files/folder 1/folder 2/"folder 3"/
./x007_shorter.sh: line 4: cd: ./folder 3/: No such file or directory
ls: cannot access */: No such file or directory

这里是程序:

#!/bin/bash
function findir {
    newDir=$1
    eval cd $newDir
    ARRAY=( $(ls -d */) )
    declare -a diry
    count=0
    a=0
    while [ $a -lt ${#ARRAY[@]} ]; do
        diry[$count]="${ARRAY[$a]}"
        noSpace=true
        while [ true ]; do
            if [[ ${diry[$count]} == */* ]] ; then
                if [ $noSpace = false ]; then
                diry[$count]="${diry[$count]:0:((${#diry[$count]}-1))}\"/"
                fi
                break
                noSpace=true
            fi
            let "a=$a+1"
            if [ $noSpace = false ]; then
                diry[$count]="${diry[$count]} ${ARRAY[$a]}"
            else
                diry[$count]="\"${diry[$count]} ${ARRAY[$a]}"
            fi
            noSpace=false
        done
        let "count=$count+1"
        let "a=$a+1"
    done
    for a in `seq 1 ${#diry[@]}`; do
        eval cd .$newDir
#        list "${diry[($a-1)]}"
        where=`pwd`
#        eval cd $newDir
        #findir "${diry[($a-1)]}"
        #findir "$where${diry[($a-1)]:1}"
        #Right option won,  echo "${diry[($a-1)]} Vs $where/${diry[($a-1)]}"
        echo "$where/${diry[($a-1)]}"
        findir "./${diry[($a-1)]}"
    done
}
function list {
    input_file_directory=$1
    eval cd $input_file_directory
    ARRAY=( $(find . -maxdepth 1 -type f -print) )
    declare -a files
    count=0
    a=0
    while [ $a -lt ${#ARRAY[@]} ]; do
        files[$count]="${ARRAY[$a]}"
        while [ true ]; do
            if [[ ${ARRAY[(($a+1))]} == ./* ]] ; then
                break
            fi
            if [[ "${ARRAY[(($a+1))]}" == "" ]] ; then
                break
            fi
            let "a=$a+1"
            files[$count]="${files[$count]} ${ARRAY[$a]}"
        done
        let "count=$count+1"
        let "a=$a+1"
    done
    where=`pwd`
    for a in `seq 1 ${#files[@]}`; do
        echo "$where${files[($a-1)]:1}"
        #going to work on each file, just echoing file till lists all files
    done
}

clear
dar=""
if [[ $1 = "" ]]; then
    read -p "Please enter a directory for me to scan" newdir
    dar=$newdir
    list $newdir
    findir $newdir
else
    dar=$1
    list $1
    findir $1
fi

Answer 1:

克里斯·J的答案是做的事情,如果你可以把每个文件的东西,在一个单独的命令(/脚本)的首选方式。 如果你想在一个脚本的一切,我最喜欢的咒语是这样的:

while IFS="" read -r -d $'\000' file <&3; do
    dostuffwith "$file"
done 3< <(find -x  "$dir" -mindepth 1 -type f -print0)

见BashFAQ#20和#89的解释和一些其他的选择。 需要注意的是在bash这只作品(即脚本必须以#!/斌/庆典)。 此外,它处理给定目录的内容按字母顺序,而不是文件前方的子目录。

如果你真的想“手”来逐步通过文件(即获得通过遍历顺序更多的控制),这里就是我会做:

#!/bin/bash

process_dir() {
    local -a subdirs=()
    echo "Scanning directory: $1"

    # Scan the directory, processing files and collecting subdirs
    for file in "$1"/*; do
        if [[ -f "$file" ]]; then
            echo "Processing file: $file"
            # actually deal with the file here...
        elif [[ -d "$file" ]]; then
            subdirs+=("$file")
            # If you don't care about processing all files before subfolders, just do:
            # process_dir "$file"
        fi
    done

    # Now go through the subdirs
    for d in "${subdirs[@]}"; do
        process_dir "$d"
    done
}

clear
if [[ -z "$1" ]]; then
    read -p "Please enter a directory for me to scan " dir
else
    dir="$1"
fi
process_dir "$dir"


Answer 2:

任何原因,你不能使用找到呢? 坚持你在它自己的脚本,希望每个文件操作(我把它叫做低于dostufftomyfile.sh),然后执行:

find $dir -type f -print0 | xargs -0 dostufftomyfile.sh

更换$ DIR你会从被搜索的顶级目录...

编辑补充...当你写的shell脚本,请确保你把$ @在双引号...例如,你会希望你的dostufftomyfile.sh脚本有这样的结构:

#!/bin/sh
for f in "$@"
do
    echo "Processing file: $f"
    # Do something to file $f
done

如果你不报$ @然后在文件名中的空间将被忽略(我怀疑你不会想):-)



Answer 3:

你有错误"No such file ....由于这个

ARRAY=( $(ls -d */) )

当它的扩大,空格目录将获取存储在阵列作为单独的元素。 例如Desktop/test_files/folder 1/folder 2/"folder 3"/

在阵列中,元素0将是Desktop/test_files/folder ,元件1将是1/folder等。 这就是为什么你的脚本找不到目录。

您可以设置IFS为$“\ n”分配给前阵

OLDIFS=$IFS
IFS=$'\n'
ARRAY=($(ls -d */))
IFS="$OLDIFS"


文章来源: ubuntu/linux bash: traverse directory and subdirectories to work with files
标签: linux bash shell