個々の出力ラインを変数に保存

個々の出力ラインを変数に保存

私はこの機能を使用して、find -mtime -2過去24時間以内に変更されたファイルを見つけます。出力は次のとおりです。

/home/user/logs/file-2014-08-22.log
/home/user/logs/file-2014-08-23.log

出力の最初の行を変数に保存し、次の行を別の変数に保存する必要があります。ただ置くことはできません。私はあなたが何を提案しているのかを知っていますが、| grep 22これは23何度も実行されるbashスクリプトの一部であり、次に別の名前のファイルセットがあるので、あまりにもgrep具体的です。これは可能ですかawk?それでは、どうすればいいですか? 。

答え1

ファイル名にスペースなどがないと仮定すると、これを行ういくつかの方法があります。 1つは配列を使用することです。

files=( $(find -mtime -2) )
a=${files[1]}
b=${files[2]}

filesfindすべてのパス出力の配列が順番に配列され、ゼロから始まるインデックスが付けられます。希望の行を取得できます。ここでは、2行目と3行目をaandに格納しbますが、配列要素を直接使用することもできます。

そのオプションを使用するGNU findまたは他の選択肢がある場合は、次のようにprintf使用します。readそしてプロセスの交換:

read junk a b junk < <(find -printf '%p ')

これはfindすべての出力を1行に変換し、その行をinputに供給して最初の単語read(パス)をjunk,2番目の単語に保存しa、3番目の単語を保存し、行bの残りの部分を保存してjunk繰り返します。

同様に紹介することもできます。paste注文するすべてのPOSIX互換システムに同じ効果があります。

read junk a b junk < <(find -mtime -2 | paste -s)

paste -s入力をタブ区切りの単一行に変換してread再処理できます。

通常、メインコマンドを複数回実行したい場合(ここでは不要です)、次のものを使用できます。sed容易に:

find | sed -n 2p

-n通常の出力抑制を使用して印刷用に2行目を選択すると、出力の2行目のみが印刷されますp。同じ効果を得るheadためにそれらを一緒に接続することもできます。これは非常に長いファイルでより効率的です。tail

上記の内容はすべて、2行目と3行目、および保存するのとa同じ効果があり、bファイルに空白、タブ、改行、その他の文字がないと仮定しています。入力フィールド区切り記号(IFSすべてのファイル名の値です。


しかし、出力順序に注意してください。find定義されていないので、「2番目のファイル」は、ソートのために他の方法で設定しない限り、実際には有用な識別子ではありません。ほとんどの場合、生成順序に近いかもしれませんが、すべてではありません。

答え2

渡すとbash 4.x使えますマップファイル:

$ mapfile -t <<< "$(find -mtime -2)"
$ printf "%s\n" "${MAPFILE[0]}"
/home/user/logs/file-2014-08-22.log
$ printf "%s\n" "${MAPFILE[1]}"
/home/user/logs/file-2014-08-23.log

mapfile標準入力の行をインデックス配列変数として読み込みます。デフォルトの配列はですMAPFILE。配列名を指定できます。

mapfile -t array <<< "$(find -mtime -2)"

-tオプションを使用すると、mapfile読み取った各行から末尾の改行が削除されます。

答え3

既知の数のファイルやコード、またはコマンドラインで見つかった重複エントリに制限する代わりに、次の(長いですが)行を使用して各出力に連続した変数名を割り当てることができますfind

行/スクリプト:

$ counter=0; for log_file in $(find -mtime -2); do echo $log_file; if [ -f $log_file ]; then ((counter++)); eval var_$counter=`readlink -f $log_file`; fi; done

行が削除されない場合は、次のように出力されます(通常はfind)。echo

.
./logs
./logs/file-2014-08-22.log
./logs/file-2014-08-23.log

ただし、ここではオプションを使用して有効なファイルをフィルタリングしますif -f ....ここ)、したがって必要な情報を保持します。

$ echo $counter
2
$ echo $var_1
/home/shadowe/Videos/logs/file-2014-08-22.log
$ echo $var_2
/home/shadowe/Videos/logs/file-2014-08-23.log

したがって、シーケンス変数には結果への絶対パスが含まれており、find既存のスクリプトと簡単にマージできます。

関連情報