web-dev-qa-db-ja.com

長いリストフィールドを抽出するにはどうすればよいですか?

シェルスクリプトでファイルのアクセス日を抽出したい。次のスクリプトを書いてみましたが、うまくいきません。エコーaccessdayの場合、出力は「スタッフ」です。

file=$1
accessday=$(ls -lu $file | cut -d ' ' -f 6)
2
Out Of Bounds

lsを解析しないでください

これはstatの仕事です。

人間が読める形式で最終アクセス時間を取得するには:

stat -c '%x' file.txt

エポックからの秒数:

stat -c '%X' file.txt
5
heemayl

lsの出力の解析は 困難で常に可能とは限りません です。タイムスタンプを抽出する場合は、必要なフォールバックになることがあります(これは、移植可能な唯一の方法です。すべてのシステムにstatコマンドがあるわけではありません)が、人間が読める形式のタイムスタンプを取得します。 機械可読形式に変換するのは難しい 。少なくとも難しい部分を邪魔にならないようにします。-oおよび-gオプションを渡して、ユーザーフィールドとグループフィールドを省略します(これらは一部のシステムでスペースを含む可能性があり、の出力で区切ることができません。 ls)。次に、タイムスタンプはフィールド4〜6(1からの番号付け)を占有します。

変数展開を二重引用符で囲むことを忘れないでください

access_time=$(ls -dlogu -- "$file" | awk '1 {print $4, $5, $6}')

月の日が必要な場合は、過去6か月以内のタイムスタンプについて、2つの出力形式を区別する必要があります。信頼できる出力形式を取得するには、ロケールをCに設定します。この形式では、日は常に2番目のタイムスタンプフィールドです。

access_day=$(ls -dlogu -- "$file" | awk '1 {print $5}')

ls -luの典型的な出力を見ると、

-rw-r--r--  1 someuser  somegroup  74 Mar 29 05:21 filename

グループ名の前に合計5文字のスペース文字があることに気付くでしょう。したがって、cutコマンドでフィールド6を指定すると、グループ(この場合は「スタッフ」)が返されます。

また、アクセス日は、表記の6ではなくフィールド7になります。

1つの解決策は、awkを使用することです。これは、フィールド区切り文字の複数の出現をデフォルトで期待した方法で処理するためです。

accessday=$(ls -lu $file | awk '{print $7}')
2
Guido

あなたの質問に基づいて、私はstatを使用して出力を正規化し、次にカットして必要な日付のみを表示します。

stat -c '%x' FILENAME | cut -c 9,10

2
Randy