假设我有一个目录结构如下
test
test/a
test/b
现在我想执行一个命令,以便在.
文件夹中我可以对文件a
和b
.
所以基本上,我想要这样的东西,我天真地尝试过
find test -type f -exec touch `basename {}` \;
只是,这不会导致空文件a
和b
父目录。假设我的 touch 命令只能采用一个参数。
这将导致像这样的目录结构
a
b
test
test/a
test/b
我知道如何在 bash 脚本中执行此操作,但我对单命令解决方案感兴趣。
答案1
执行bash。
find ... -exec bash -c 'touch "${1##*/}"' btouch {} \;
这里的${1##*/}
意思是:从第二个以 a 结尾的参数中删除最长的匹配/
,从而保留最后一个之后的所有内容/
。
btouch
可以是任何虚拟名称,以使其正确显示在活动进程列表中 ( ps
)
答案2
尝试此操作需要您自担风险:
find test -type f -exec echo touch \"\$\(basename "'{}'"\)\" \; | bash
使用带空格的文件名进行测试。
答案3
尝试execdir
使用以下选项find
:它执行您在文件目录中指定的命令,仅使用其基本名称作为参数
据我所知,您想在“main”目录中创建“a”和“b”。我们可以通过组合$PWD
和-execdir
选项来做到这一点。看看下面的解决方案。 (这些&& find … ls
部分仅用于输出,因此您可以看到效果。您需要在 之前使用该命令&&
。)
首先我搭建测试环境:
-----[ 15:40:17 ] (!6293) [ :-) ] janmoesen@mail ~/stack
$ mkdir test && touch test/{a,b} && find . -exec ls -dalF {} +
drwxr-xr-x 3 janmoesen janmoesen 4096 2012-05-31 15:40 ./
drwxr-xr-x 2 janmoesen janmoesen 4096 2012-05-31 15:40 ./test/
-rw-r--r-- 1 janmoesen janmoesen 0 2012-05-31 15:40 ./test/a
-rw-r--r-- 1 janmoesen janmoesen 0 2012-05-31 15:40 ./test/b
这就是当您使用简单的方法时会发生的情况-exec
- 原始文件被触及:
-----[ 15:40:30 ] (!6294) [ :-) ] janmoesen@mail ~/stack
$ find test -type f -exec touch {} \; && find . -exec ls -dalF {} +
drwxr-xr-x 3 janmoesen janmoesen 4096 2012-05-31 15:40 ./
drwxr-xr-x 2 janmoesen janmoesen 4096 2012-05-31 15:40 ./test/
-rw-r--r-- 1 janmoesen janmoesen 0 2012-05-31 15:40 ./test/a
-rw-r--r-- 1 janmoesen janmoesen 0 2012-05-31 15:40 ./test/b
但是,如果我们$PWD
与参数占位符结合{}
使用-execdir
,我们就可以实现(我认为)您想要的:
-----[ 15:40:57 ] (!6295) [ :-) ] janmoesen@mail ~/stack
$ find test -type f -execdir touch "$PWD/{}" \; && find . -exec ls -dalF {} +
drwxr-xr-x 3 janmoesen janmoesen 4096 2012-05-31 15:41 ./
-rw-r--r-- 1 janmoesen janmoesen 0 2012-05-31 15:41 ./a
-rw-r--r-- 1 janmoesen janmoesen 0 2012-05-31 15:41 ./b
drwxr-xr-x 2 janmoesen janmoesen 4096 2012-05-31 15:40 ./test/
-rw-r--r-- 1 janmoesen janmoesen 0 2012-05-31 15:40 ./test/a
-rw-r--r-- 1 janmoesen janmoesen 0 2012-05-31 15:40 ./test/b
答案4
调用 shell 对路径进行一些字符串处理。您可以使用${VARIABLE##PATTERN}
字符串操作构造来剥离前缀匹配PATTERN
—VARIABLE
模式*/
会剥离前导目录名称。
find test -type f -exec sh -c 'for x; do touch "${x##*/}"; done' _ {} +
GNU find 的另一种方法是将其更改为子目录。调用 shell 以更改回原始目录。
find test -type f -execdir sh -c 'cd "$0" && touch -- "$@"' "$PWD" {} +
或者放弃find
并使用 zsh。具体来说,添加t
历史修改器作为一个全局限定符。
touch test/**/*(:t)