从多个目录下的文件中打印一行

从多个目录下的文件中打印一行

我有以下任务:

我有几个用户目录。在某些用户目录中,有一个名为 的文件夹myFolder。像这样的东西:

/home/usera/a/b/myFolder
/home/userb/a/b/myFolder
/home/userc/a/b/
/home/userd/a/b/myFolder

myFolder请注意, .net 的主目录中没有userc.

里面myFolder有一个名为README.我想在控制台/文件中打印自述文件的第二行以及用户名。

我正在尝试使用“sed”,但它给了我第一个文件夹的输出。例如

sed '2!d' /home/*/a/b/myFolder/README

我可以推送此命令,但它没有给我预期的输出。我正在寻找的理想输出是这样的:

usera - v2.2
userb - v2.1
userd - v2.2

我对输出的格式化方式很灵活。但是,它应该打印用户名,并且README文件的第二行是可读的。

知道如何实现这一目标吗?

答案1

通过awk支持该nextfile指令的实现,您可以执行以下操作:

awk 'FNR == 2 {print; nextfile}' /home/*/a/b/myFolder/README

它也可以与不支持的 awk 实现一起使用nextfile,但效率较低,因为它会完全读取文件。

在 中sed,为了使2地址匹配每个文件的第二行而不是整个输入的第二行,您需要-sGNU 实现的选项sed

sed -s '2!d' /home/*/a/b/myFolder/README

但这也意味着所有文件都被完全读取,而且sed,甚至 GNU 也sed没有与 gawknextfileperl'相当的东西close ARGV

perl

perl -ne '
  if ($. == 2) {print; close ARGV} else {close ARGV if eof}
  ' /home/*/a/b/myFolder/README

打印用户名:

awk '
  FNR == 2 {
    split(FILENAME, f, "/")
    print f[3] ": " $0
    nextfile
  }' /home/*/a/b/myFolder/README
perl -ne '
  if ($. == 2) {
    print((split "/", $ARGV)[2] . ": $_");
    close ARGV;
  } else {
    close ARGV if eof;
  }' /home/*/a/b/myFolder/README

答案2

for folder in /home/*/a/b/myFolder; do
  if [ -f "$folder/README" ]; then
    version=$(sed '2!d' "$folder/README")
    username=$(basename $(dirname $(dirname $(dirname $folder) ) ) )
    echo "$username - $version"
 fi
done

如果我要解决这个问题,我将使用针对用户名的通配符循环遍历公共基目录以匹配所有用户,测试路径是否有文件README,如果有,则从文件中提取第二行,然后提取文件路径中的用户名。

答案3

使用 find,您可以查找文件,并对每个文件执行操作或执行命令:

find /home -path '/home/*/a/b/myFolder/README' -printf '%h - ' -exec sed '2!d' {} \;

相关内容