Tar*_*lpe 9 command-line bash scripts
我有一些带有\n
字符名称的文件夹。
例如:
$ ls
''$'\n''Test'
Run Code Online (Sandbox Code Playgroud)
那是指一个带有测试名称的文件夹,名称前有一个空行。
因此,当我在其父目录中运行一些这样的脚本时:
while IFS= read -r d; do
rmdir $d
done < <(find * -type d)
Run Code Online (Sandbox Code Playgroud)
表明:
rmdir: failed to remove '': No such file or directory
rmdir: failed to remove 'Test': No such file or directory
Run Code Online (Sandbox Code Playgroud)
因为它运行了两次,一次 on\n
和另一个 on Test
,因为文件夹名称有两行。
那么我该如何解决这个问题,让脚本知道\nTest
只有一个文件夹?
Ser*_*nyy 12
您在那里只有一个命令,因此find
使用-exec
标志调用进行调用就足够了rmdir
:
find -depth -type d -exec rmdir {} \;
Run Code Online (Sandbox Code Playgroud)
或者使用 中的-delete
选项 find -type d -delete
,但它不适用于非空目录。为此,您还需要-empty
标志。还要注意,-delete
意味着-depth
可以跳过。因此,另一种可行的替代方法是将所有内容都作为一个过程:
find -type d -empty -delete
Run Code Online (Sandbox Code Playgroud)
如果目录不为空,请使用rm -rf {} \;
. 要仅隔离具有\n
in 文件名的目录,我们可以将 bash 的ANSI-C 引用 $'...'
与-name
选项结合起来:
find -type d -name $'*\n*' -empty -delete
Run Code Online (Sandbox Code Playgroud)
POSIX-ly,我们可以这样处理:
find -depth -type d -name "$(printf '*\n*' )" -exec rmdir {} \;
Run Code Online (Sandbox Code Playgroud)
值得一提的是,如果您的目标是删除目录,那么-delete
就足够了,但是如果您想在目录上执行命令,则-exec
最合适。
也可以看看
Byt*_*der 10
您可以使用 shell globs 而不是find
:
for d in */ ; do
rmdir "$d"
done
Run Code Online (Sandbox Code Playgroud)
shell glob*/
匹配当前目录中的所有文件夹。这个 for 循环结构会自动处理正确的分词。
请注意,根据您的 shell 选项,这可能会忽略隐藏文件夹(名称以 . 开头)。可以使用命令更改该行为以匹配当前会话的所有文件shopt -s dotglob
。
也不要忘记总是引用你的变量。
到目前为止编写的两个答案rmdir
每个目录调用一次,但是rmdir
我想知道可以使用多个参数:没有更有效的方法吗?
一个可以简单地做
rmdir */
Run Code Online (Sandbox Code Playgroud)
这绝对是最简单和最有效的方法,但在许多目录的情况下可能会引发错误(请参阅gnome-terminal 中命令行参数的最大长度是多少?)。如果您希望这种方法以递归方式工作,请启用globstar
shell 选项shopt -s globstar
并使用**/*/
代替*/
。
使用 GNU find
(如果我们不只是想使用-delete
),我们可以做
find -depth -type d -exec rmdir {} +
Run Code Online (Sandbox Code Playgroud)
它构建命令行的方式“与xargs
构建其命令行的方式大致相同”(man find
)。替代-depth
的-maxdepth 1
,如果你不希望它递归工作。
steeldriver 在这个答案中解释了第三种和 IMO 的绝妙方法:
printf '%s\0' */ | xargs -0 rmdir
Run Code Online (Sandbox Code Playgroud)
这使用内置的 shellprintf
来构建一个以零分隔的参数列表,然后将该列表通过管道传输到xargs
该列表,rmdir
根据需要的频率进行调用。你可以让它递归地工作,shopt -s globstar
而**/*/
不是*/
像上面那样。
归档时间: |
|
查看次数: |
1017 次 |
最近记录: |