unix bash - 保存环境变量和循环
假设您的目录中有一个first.sh 文件:“/home/userbob/scripts/foo/”。基本上我想知道如何循环遍历特定目录,每次都返回到更高级别的目录并重复。
.sh 文件有类似这样的伪代码:
#!/bin/bash
curdi={$PATH} #where the first.sh file sits on the server
FOLDERS="$curdi/waffles/inner/
$curdi/pancakes/inner/
$curdi/bagels/inner/"
for f in $FOLDERS
do
cd $f
cp innerofinner/* .
cd $curdi
done
这个想法是以某种方式将 /home/userbob/scripts/foo/waffles/inner/innerofinner 的所有内容复制到 /home/userbob/scripts/foo/waffles/inner/ (基本上只是重复有煎饼、百吉饼等的路径。)
无法对 /home/userbob/scripts/foo/ 下的所有目录(*)执行此操作,因为有一些我不想复制。
Let's say you have a first.sh file in a directory: "/home/userbob/scripts/foo/". Basically I would like to know how to loop through specific directories, each time going back up to a higher level directory and repeating.
The .sh file has something like this pseudocode:
#!/bin/bash
curdi={$PATH} #where the first.sh file sits on the server
FOLDERS="$curdi/waffles/inner/
$curdi/pancakes/inner/
$curdi/bagels/inner/"
for f in $FOLDERS
do
cd $f
cp innerofinner/* .
cd $curdi
done
The idea is to somehow copy all the contents of /home/userbob/scripts/foo/waffles/inner/innerofinner to /home/userbob/scripts/foo/waffles/inner/
(and basically repeating just with the path having pancakes, bagels.etc.)
Can't do it for all directories (*) under /home/userbob/scripts/foo/ because there are some that I don't want to copy.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
这应该可以做到:
This should do it:
行走文件树?听起来像是
find
的工作!我做了一个部分路径并假设工作目录为
/home/userbob/scripts/foo
。绝对路径也可以,看起来像这样这会找到列出的目录下一层名为“innerofinner”的所有目录,并在其父目录中执行 bash 和一个简单的 cp 脚本。
如果您想知道这是如何工作的,请阅读下文。
dirs=()
语法创建一个名为dirs
的空数组。dirs+(ab)
创建一个数组,其中a
位于索引 0 处,b
位于索引 1 处。任何以空格分隔的字符串都可以在此处使用。在 shell 脚本中,{a,b,c}
扩展为ab c
,但A{a,b,c}B
扩展为>AaB AbB AcB
。因此,指定{bagels,pancakes}/inner
只是表示bagels/inner
和pancakes/inner
的一种方式,而无需输入太多内容。bash 中的变量可以用
$foo
或${foo}
扩展;这些是相同的。 shell 中的数组可以使用${foo[@]}
扩展为其所有元素,并用空格分隔(如果您了解 perl 或 php,这将有意义)并引用扩展(始终是shell 中的好主意!)防止变量内部的空格再次被 shell 处理。因此,"${dir[@]}"
变为bagels/inner pancakes/inner
。知道了这一点,我们看到 find 命令已变成
find bagels/inner pancakes/inner -maxdepth 1 -mindepth 1 -type d -name innerofinner
如果执行此命令,它将返回两行:都是完整的每个innerofinner
目录的路径。我们现在想要的就是为每个人做一些事情,-execdir
做得很好。Walking file trees? Sounds like a job for
find
!I did a partial path and assumed a working directory of
/home/userbob/scripts/foo
. An absolute path would work, too, and would look likeThis finds all directories exactly one level below the listed directory that are named "innerofinner" and, in their parent directories, executs bash and a simple
cp
script.If you're wondering how this works, read below.
The
dirs=()
syntax creates an empty array nameddirs
.dirs+(a b)
creates an array witha
at index 0 andb
at index 1. Any whitespace-delimited string will work, here. In a shell script{a,b,c}
expands toa b c
butA{a,b,c}B
expands toAaB AbB AcB
. So specifying{bagels,pancakes}/inner
is just a way to say bothbagels/inner
andpancakes/inner
without having to type as much.A variable in bash can be expanded with
$foo
or with${foo}
; these are the same. An array in shell can be expanded to all of its elements with${foo[@]}
delimited by spaces (if you know perl or php this will make some sense) and quoting the expansion (always a good idea in shell!) prevents spaces innside the variable from being processed again by the shell. Thus,"${dir[@]}"
becomesbagels/inner pancakes/inner
.Knowing this we see that the find command has become
find bagels/inner pancakes/inner -maxdepth 1 -mindepth 1 -type d -name innerofinner
and if you execute this it will return exactly two lines: both full paths to eachinnerofinner
directory. All we want now is to do something for each one, which-execdir
does nicely.使用递归函数或递归调用脚本。
Use a recursive function or invoke the script recursively.
我不确定我是否正确理解您的问题陈述。你的伪代码看起来不错。但是,我发现以下行有问题。
它不会为您提供脚本所在的目录,而是提供您所在的目录。如果您的脚本目录位于路径中并且您从主目录运行脚本,则 $curdi 将指向您的主目录而不是目录你的脚本所在的位置。这将导致不希望的结果。
I am not sure if I understand your problem statement correctly. Your psuedo code seems good. But, I see a problem with the following line.
It does not give you the directory where the script resides but gives the directory you are in. If your script directory is in the path and you are running the script from your home directory then $curdi would point to your home directory and not the directory where your script resides. This will lead to undesired results.
顺便说一句,如果您确实想按照伪脚本尝试的方式执行此操作,则可以这样做假设
$PWD
对您来说是“当前”目录的足够好的指示符。我,我会把它传递给脚本。称其为
Incidentally, if you really wanted to do it in the way that your pseudo-script attempts it, you'd do it like this
Presuming that
$PWD
is a good enough indicator of "current" directory for you. Me, I'd pass it in to the script.at call it like
应该做。查找所需子目录中的每个文件,然后根据其名称复制它。
华泰
Should do. Finds every file in the desired subdirs, then copies it based on its name.
HTH