bash 单行代码/脚本对没有关联文件的文件执行命令

问题描述 投票:0回答:3

以下代码对所有类型为

do_x.sh
的文件递归执行
a_???.json
。但是,我想对这些文件的子集执行相同的操作,这些文件没有具有相同名称和不同扩展名的相应文件。

 find $PWD -type f -name "a_???.json"  | xargs -I{} do_x.sh {}

我该如何在同一句话中说,做同样的事情,但只对没有相应

a_???.json
的文件
a_???.json
完成?以下不是确定的解决方案:

find $PWD -type f -name "a_???.json" -exclude "a_???.json.done" | xargs -I{} do_x.sh {}
Example
a_111.json
a_112.json
a_111.json.done

因此,仅在

do_x.sh
 上执行 
a_112.json

bash find xargs
3个回答
1
投票

要保持脚本的相同结构,请尝试以下操作:

find $PWD -type f -name "a_???.json" -execdir bash -c 'test ! -f {}.done' \; -print | xargs -I{} do_x.sh {}

0
投票

您可以使用

xargs
通过命令
bash -c
运行shell代码。这允许您使用同一命令处理多个
find
点击,如果您有很多文件,这可能会带来显着的性能改进:

find "$PWD" -type f -name "a_???.json" -print0 |
   xargs -0 -r bash -c 'for f; do [[ -e "${f}.done" ]] || do_x.sh "$f"; done' bash

为了便于阅读,我将其分成两行,但它是一条管道。

请注意,没有显式参数项的

for
循环会在位置参数上运行,这就是 shell 从
find
接收文件名的方式。

另请注意,尾随的

bash
是有意且必要的,或者至少在该位置需要 something,否则
find
发出的第一个文件将被用作 shell 的
$0
,其中命令运行。


0
投票

if
中执行 shell
xargs
语句。

find "$PWD" -type f -name "a_???.json" -exec bash -c 'if ! [ -f "$1.done" ]; then do_x.sh "$1"; fi' {} {} \;

不需要使用

xargs
,您可以使用
-exec
关键字到
find
来执行命令。

由于

-exec
不使用 shell 来执行命令,因此您必须显式执行
bash -c

对于更复杂的命令,它是类似的。使用

xargs
获取并行操作,然后将完整命令放入
then
if
子句中。

find "$PWD" -type f -name "a_???.json" | 
    xargs -I{} -n1 -P10 bash -c 'if ! [ -f "$1.done" ]; then srun -N1 -A goc -p slurm do_x.sh "$1"; fi' {} {} \;
© www.soinside.com 2019 - 2024. All rights reserved.