複数ディレクトリのファイルから1行印刷

複数ディレクトリのファイルから1行印刷

私は次のようなことをします。

複数のユーザーディレクトリがあります。一部のユーザーディレクトリにはというフォルダがあります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。コンソール/ファイルにユーザー名とともに追加情報の2行目を印刷したいと思います。

「sed」を使用しようとしていますが、最初のフォルダの出力が表示されます。例えば

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

このコマンドをプッシュできますが、期待した結果は出ません。私が探している理想的な出力は次のとおりです。

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

出力形式を柔軟に指定できます。ただし、ユーザー名を印刷する必要があり、READMEファイルの 2 行目を読み取ることができます。

これを達成する方法についてのアイデアはありますか?

答え1

awkこのディレクティブをサポートする実装では、nextfile次のことができます。

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

サポートされていない awk 実装で使用することもできますが、nextfileファイル全体を読み取るので効率が悪くなります。

アドレスが入力全体の2行目ではなく各ファイルの2行目と一致するようsedにするには、GNU実装オプションが必要です。2-ssed

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

ただし、これはすべてのファイルを完全に読み取ることを意味し、sedGNUにもsedgawknextfileまたは 'とperl同等の機能はありません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

この問題を解決するには、共通のデフォルトディレクトリを繰り返して、ユーザー名にワイルドカードを使用するすべてのユーザーを一致させ、パスにファイルがあるかどうかをテストし、ファイルがある場合はファイルから2行目を抽出しREADME、あります。

答え3

検索を使用すると、ファイルを見つけて各ファイルに対して操作またはコマンドを実行できます。

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

関連情報