Linux分别在-exec之前和之后查找、获取输出到一个变量

Linux find, get output to a variable before and after -exec respectively

在 shell 脚本 (sh) 中,我想找到一个可执行文件,将其 运行 输出保留在一个变量中,并将其路径保留在另一个变量中。

假设我想找到所有已安装的 OpenCV 版本,然后将主要版本保留在一个变量中,将文件的位置保留在另一个变量中。

list=$(find / -type f -name opencv_version -exec {} \; 2>/dev/null | sort -u | cut -c-1); printf "%c;" $list

会 return 说 3;4;但我还想要版本 3 和版本 4 的 opencv_version 文件位置。 为此,我需要将第一部分 find / -type f -name opencv_version 的输出存储在另一个变量中,在 运行ning -exec {} \;

之前

我可以在一个班轮中完成这两个操作吗?

使用-print-exec,把输出处理放在一个shell

例如,在我的 mac 上,通过自制软件安装了 GNU awk:

find -L /usr -name awk -type f -executable \
             -print \
             -exec sh -c '"" --version | head -n 1' sh {} \;  2>/dev/null

产出

/usr/bin/awk
awk version 20200816
/usr/local/bin/awk
GNU Awk 5.1.1, API: 3.1 (GNU MPFR 4.1.0, GNU MP 6.2.1)
/usr/local/var/homebrew/linked/gawk/bin/awk
GNU Awk 5.1.1, API: 3.1 (GNU MPFR 4.1.0, GNU MP 6.2.1)
/usr/local/var/homebrew/linked/gawk/libexec/gnubin/awk
GNU Awk 5.1.1, API: 3.1 (GNU MPFR 4.1.0, GNU MP 6.2.1)
/usr/local/opt/gawk/bin/awk
GNU Awk 5.1.1, API: 3.1 (GNU MPFR 4.1.0, GNU MP 6.2.1)
/usr/local/opt/gawk/libexec/gnubin/awk
GNU Awk 5.1.1, API: 3.1 (GNU MPFR 4.1.0, GNU MP 6.2.1)
/usr/local/Cellar/gawk/5.1.1/bin/awk
GNU Awk 5.1.1, API: 3.1 (GNU MPFR 4.1.0, GNU MP 6.2.1)
/usr/local/Cellar/gawk/5.1.1/libexec/gnubin/awk
GNU Awk 5.1.1, API: 3.1 (GNU MPFR 4.1.0, GNU MP 6.2.1)

这些行可以成对处理。

建议将排序文件列表读入数组。

然后打印每个数组元素及其执行结果:

readarray -t fileNamesArr < <(find / -type f -name opencv_version -executable 2>/dev/null | sort -u)
for aFileName in ${fileNamesArr[@]}; do printf "%s; %c\n" $aFileName $(aFileName); done

补充建议,如果可能的话使用locate命令。它更快更简单。如果您经常使用 updatedb.

更新文件列表

正在测试此解决方案

正在读取 已排序 计算机中所有服务文件的列表。 比起每个 serviceFile 打印它的路径和它的字符数。

readarray -t servicesArr < <(locate "*.service"|sort -u)
for serviceFile in ${servicesArr[@]}; do 
  printf "%s; %s\n" "$serviceFile" $(cat "$serviceFile"| wc -m );
done

awk 相同的解决方案。

将排序的文件名列表读入 awk 脚本:

从当前文件名准备一个printf命令。还有 运行 它。

   awk '{
     bash_script = "printf \"%s; %c\n\" "[=12=]" $("[=12=]")";
     system("bash -c '\''" bash_script "'\''");
   }' <<< $(find / -type f -name opencv_version -executable 2>/dev/null | sort -u)

我想我毕竟不需要 -exec。这对我有用:

for i in $(find / -type f -name opencv_version 2>/dev/null); do printf '%c in %s\n' $($i) $i; done

这将 return 类似于:

4 in /usr/bin/opencv_version

3 in /home/user/opencv/build/bin/opencv_version