他のコマンドの出力である変数を繰り返します。

他のコマンドの出力である変数を繰り返します。

こんにちはスクリプトを学びに来ました。 「for」ループを使用して簡単なスクリプトを作成しようとしています。

userというフォルダに何百ものフォルダがあります。
このコマンドを実行すると、別のフォルダに移動する必要があるフォルダの一覧が表示されます。

cat failed | awk -F ":" '/FAILED/ {print $1}' |  uniq

つまり、操作に失敗したユーザーの下のフォルダをusers / failed / failedusersに移動する必要があります。

私が今やっていることは、まず次のように新しいファイルを作成することです。

cat failed | awk -F ":" '/FAILED/ {print $1}' |  uniq > failedusers

その後、次のコマンドを使用してフォルダを移動しました。

while read line; do cp -r users/$line users/failed; done < failedusers

私の質問はただ使用できますか?~のため出力を別のファイルに書き込み、次を使用する代わりにコマンド読みながら完了するためのコマンドですか?

たとえば、次のようにループ内の変数に値を割り当てます。

faileduser=`cat failed | awk -F ":" '/FAILED/ {print $1}' |  uniq`

次に、次のように書きます。

mv users/$faileduser user/failed/$faileduser

上記の内容を作成しようとすると、さまざまなエラーが発生します。

ありがとう

ベストアンサー1

GNUxargsとkshスタイルのプロセス交換をサポートするシェルを使用すると、次のことができます。

xargs -rd '\n' -I USER -a <(awk -F : '/FAILED/ {print $1}' failed | sort -u
  ) cp -r users/USER user/failed/USER

これにより、zsh次のことができます。

faileduser=( ${(f)"$(awk -F : '/FAILED/ {print $1}' failed | sort -u)"} )
autoload zargs
zargs -rI USER -- $faileduser -- cp -r users/USER user/failed/USER

コピーしたいとしましょうUSER 到着 user/failed/USERつまり、コピーしてください。入力する user/failed、次のこともできます(まだ使用されていますzsh)。

(( $#faileduser )) && cp -r users/$^faileduser user/failed/

bashシェルを使用すると、次のことができます。

readarray -t faileduser < <(awk -F : '/FAILED/ {print $1}' failed | sort -u)
(( ${#faileduser[@]} )) &&
  cp -r "${faileduser[@]/#/user\/}" user/failed/

または、すべてのユーザー名の前にawk以下を追加してください。user/

readarray -t faileduser < <(awk -F : '/FAILED/ {print "user/"$1}' failed | sort -u)
(( ${#faileduser[@]} )) &&
  cp -r "${faileduser[@]}" user/failed/

ループの場合、Korn(含む、と一緒に使用することもできます)などのforシェルを使用すると、構文は次のようになります。bashzsh

for user in "${faileduser[@]}"; do
  cp -r "user/$user" "user/failed/$user"
done

zshのように短縮できます。

for user ($faileduser) cp -r user/$user user/failed/$user

そして:

faileduser=`cat failed | awk -F ":" '/FAILED/ {print $1}' |  uniq`

`...`は廃止され、廃止されたコマンドの代替形式です。$(...)

awk出力を次の場所に保存します。スカラー、配列変数ではありません。

上記のコマンド置換で直接行ったように、引数zsh拡張フラグを使用して改行文字に分割できます。f

array=( ${(f)faileduser} )

Bash(またはksh)では、globを無効にして分割を調整した後、分割+glob演算子を使用できます。

set -o noglob
IFS=$'\n'
array=( $faileduser )

(はい、bash引用されていない引数拡張はBourneシェルから継承されたバグ機能であり、zshやBourneに似た最新のシェルではなく、ほとんどのシェルに存在する暗黙の分割+glob演算子(!)を呼び出します。修理)。

おすすめ記事