让我从我需要的东西开始吧;程序被赋予一个目录,然后它将检查目录中的所有文件(工作)并对文件执行操作(等待它可以找到该部分的所有文件)。然后它会查找子目录并为每个子目录重新运行它自己。
我正在测试的目录如下所示:
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
答案 0 :(得分:6)
你有什么理由不能使用find吗?在你自己的脚本中粘贴你想要的每个文件操作(我在下面称它为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
如果你不引用$ @那么文件名中的空格将被忽略(我怀疑你不会想要): - )
答案 1 :(得分:0)
如果您可以将每个文件的内容放在单独的命令(/ script)中,那么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"
答案 2 :(得分:0)
由于此
,您收到错误"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"