让我从我需要的东西开始; 程序会被赋予一个目录,然后它将检查目录中的所有文件(工作),并对这些文件做些东西(等待它可以find这个部分的所有文件)。 那么它将查找子目录,并为每个子目录重新运行它自己。
我正在testing的目录如下所示:
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
如果你可以把每个文件的东西放在一个单独的命令(/脚本)中,Chris 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开头)。 此外,它按字母顺序处理给定目录的内容,而不是子目录之前的文件。
如果你真的想“手工”地遍历文件(即获得对遍历顺序的更多控制),下面是我该怎么做:
#!/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"
任何原因,你不能使用找到这个? 把你想要的每个文件操作放在自己的脚本中(我把它称为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
如果你不引用$ @那么文件名中的空格将被忽略(我猜你不会想要):-)
你有错误"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"