私は初心者で、自分で解決できない小さな問題があります。これが私が直面した問題です:
名前にスペースが含まれているファイルを見つけようとします。
この部分は動作しています。
find $(pwd) -type d |grep " "
その後、
awk
ファイル名全体を印刷し、目的のグループ名を使用する「手動入力」を使用して変更しました。find $(pwd) |grep " " |awk '{print "changegrp developers \""$0"\""}'
developers
グループ名を変数に設定しようとすると、実際には期待どおりに機能しません。find $(pwd) |grep " " |awk group="developers" '{print "changegrp group \""$0"\""}'
本当に構文を理解していません。手動で入力したグループはどのように機能しますか?変数で作成すると機能します。私はこの種のことが一重引用符や二重引用符などを忘れて問題を引き起こす可能性があることを知っています。
私が間違っていることを指摘してもらえますか?
答え1
group
awkに必要な変数を渡し、awkにそれを(文字列リテラルではなく)変数として処理させるには、二重引用符の外にする-v group="developers"
必要があります。
awk -v group="developers" '{print "changegrp " group " \""$0"\""}'
しかし、次のようなものを使用すると、多くの頭痛を避けることができます。
find . -type d -name '* *' -exec changegrp developers {} \;
または(changegroup
複数のファイルパラメータがサポートされている場合 - 特定のコマンドに精通していません。)
find . -type d -name '* *' -exec changegrp developers {} +
また、見ることができます
答え2
find
とを避け、awk
ディレクトリにのみ興味があるとします(最初のコードスニペットに基づいて)。
shopt -s globstar dotglob nullglob
for name in ./**/*' '*; do
[[ -d $name ]] && [[ ! -L $name ]] && changegrp developers "$name"
done
または、
shopt -s globstar dotglob nullglob
for name in ./**/*' '*/; do
[[ ! -L ${name%/} ]] && changegrp developers "$name"
done
changegrp
これは単純なループを使用して、1つ以上の名前にスペースがあるすべてのディレクトリでコマンドを実行します。サブディレクトリの**
ワイルドカードパターンを一致させることでglobstar
これを行います(シェルオプションで有効になります)。シェルbash
オプションは、シェルが一致しないパターンを削除し、隠された名前と一致するようにするために使用されます。nullglob
dotglob
-L
ここでは、ディレクトリへのシンボリックリンクをクリアするテストが使用されます(-d
テストは次のようになります)。本物ディレクトリとディレクトリへのシンボリックリンクの場合)。
上記のコードの2番目の変形では、パターンの末尾/
にaを追加してディレクトリのみを選択します。テストするときは、このスラッシュを削除する必要があります-L
。これが${name%/}
行われる作業です。
developers
これにより、文字列を変数にするのは簡単です。
shopt -s globstar dotglob nullglob
group=developers
for name in ./**/*' '*; do
changegrp "$group" "$name"
done
(このコードは以下でも機能しますchangegrp
。みんな質問の他のコードスニペットに基づいて、現在のディレクトリの内側または下にスペースを含む名前。 )