私は次のようなことをします。
複数のユーザーディレクトリがあります。一部のユーザーディレクトリにはというフォルダがあります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
-s
sed
sed -s '2!d' /home/*/a/b/myFolder/README
ただし、これはすべてのファイルを完全に読み取ることを意味し、sed
GNUにもsed
gawknextfile
または 'と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' {} \;