要扁平化目录结构,我可以这样做:
find . -type f -exec sh -c 'mv "{}" "./`basename "{}"`"' \;
Run Code Online (Sandbox Code Playgroud)
我想将以下内容作为 $FLATTEN 存储在我的个人资料中
-exec sh -c 'mv "{}" "./`basename "{}"`"' \;
Run Code Online (Sandbox Code Playgroud)
这样以后我就可以执行 find . $FLATTEN
我在存储变量时遇到问题,因为它过早地被解释。我希望将它存储为字符串文字,并且仅在 shell 上使用时进行解释,而不是在来源时进行解释。
如果使用 GNU mv
,您应该这样做:
find . -type f -exec mv -t . {} +
Run Code Online (Sandbox Code Playgroud)
与其他mv
s:
find . -type f -exec sh -c 'exec mv "$@" .' sh {} +
Run Code Online (Sandbox Code Playgroud)
你永远不应该嵌入{}
的sh
代码。这是一个命令注入漏洞,因为文件的名称被解释为 shell 代码(例如尝试使用一个名为的文件`reboot`
)。
对于引用命令替换好一点,但由于您使用的是古老的形式(`...`
而不是$(...)
),你需要躲避内双引号或将在不工作sh
的实现基于Bourne shell或AT&T的ksh(其中"`basename "foo bar"`"
会实际上被视为"`basename "
(具有`
在这些 shell 中被接受的不匹配)与foo
和 then连接bar"`"
)。
此外,当您执行以下操作时:
mv foo/bar bar
Run Code Online (Sandbox Code Playgroud)
如果bar
确实存在并且是一个目录,那实际上是一个mv foo/bar bar/bar
. mv -t . foo/bar
或者mv foo/bar .
没有那个问题。
现在,要将这几个参数 ( -exec
, sh
, -c
, exec mv "$@" .
, sh
, {}
, +
) 存储到变量中,您需要一个数组变量。支持数组的外壳是(t)csh
, ksh
, bash
, zsh
, rc
, es
, yash
, fish
。
并且为了能够直接使用该变量$FLATTEN
(而不是"${FLATTEN[@]}"
在 ksh/bash/yash 或$FLATTEN:q
in 中(t)csh
),您需要一个具有合理数组实现的外壳:rc
,es
或fish
. 还zsh
在这里,这些参数都不是空的。
在rc
/ es
/ zsh
:
FLATTEN=(-exec sh -c 'exec mv "$@" .' sh '{}' +)
Run Code Online (Sandbox Code Playgroud)
在fish
:
set FLATTEN -exec sh -c 'exec mv "$@" .' sh '{}' +
Run Code Online (Sandbox Code Playgroud)
然后你可以使用:
find . -type f $FLATTEN
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1689 次 |
最近记录: |