`ls -l`の出力からフィールド/列を選択するにはどうすればよいですか?


22

私の目標は一見シンプルです(少なくとも私にとって)。ls -lまたはの出力を取得し、ls -lh1つのフィールドのみを選択します。

私はこれを可能な限り防弾とすることを探しています。つまり、ファイル名には可変数のスペースを含めることができ、フィールド内のすべてが同じ長さであるとは限らないと想定しています

フィールドの名前(または単にフィールド番号)を取得し、フィールドの内容を返すスクリプトを作成することのボーナスポイント。

回したい

ここに画像の説明を入力してください

に:

ここに画像の説明を入力してください

回答:


41

試してくださいls -l | awk '{print $7}'

awk このタスクに最適なように列を選択します。


3
@ormaajによって説明:Doが持つ特定の場所で利用可能であることの情報に依存しませんls。このfindコマンドは非常に役立ちます。
水田ランダウ

@PaddyLandau findコマンドを使用して、ファイルサイズをメガバイト単位で印刷するにはどうすればよいls -l --block-size=Mですか?
SurpriseDog

@Benjamin — lsコマンドはPOSIX標準ではないため、依存するスクリプトlsは異なるシステムで、または時間が経つと壊れる可能性があります。詳細については、このページの@ormaajによる回答を参照してください。求めることを行う1つの方法は、Bashループを使用することです。以下に例を示します。for FILENAME in *; do FILESIZE=$(( $( stat --format=%s "${FILENAME}" ) / 1024 )); echo "${FILENAME}" ${FILESIZE}; done。もちろん、ではなくecho、処理を使用します。
水田ランダウ

@PaddyLandau私はちょうど... | xargs -d '\n' du -m同様に動作するfindコマンドの出力をパイプでつないでしまいました。
SurpriseDog

@Benjaminの-execオプションをご覧くださいfind
水田ランダウ

17

lsを解析しないでください。GNUを使用しますfind。または、移植性が重要でない場合は、stat(1)

find . -maxdepth 1 -printf '%Td\n'

ファイル名のリスト以外のデータを1行ずつ読み取り、フィールドに分割する方法については、BashFAQ / 001を参照してください

ほとんどの状況で意味をなすファイル名の改行区切りリストを確実に読み取る方法はありません。


1

次のようにシェルで特定の列をフェッチできます。

ls -al | while read perm bsize user group size month day time file; do echo $day; done

またはawkに示すように@Coreyの答えcut -c44-45また、調整後の作業(以降しまうlsの列を固定している)、または任意の他は、しかし、主な問題はそれが信頼性が高く、防弾ではないだろうということである(例えばUnix上で、それはかもしれ$6、ない$7、それ引数に応じて変化します)マシンフレンドリーではないlsためコマンドを解析することはまったくお勧めできません

最適なのは、必要な出力をフォーマットするための関連オプションを提供できる、findまたはなどの使用可能なさまざまなコマンドを使用するstatことです。例えば:

$ stat -c "%x %n" *
2016-04-10 04:53:07.000000000 +0100 001.txt
2016-04-10 05:08:42.000000000 +0100 7c1c.txt

数日間の変更の列を返すには、次の例を試してください。

stat -c "%x" * | while read ymd; do date --date="$ymd" "+%d"; done

GNU statがBSD statに対して異なるオプションを持っている可能性があることに注意する価値があります。


1
+1は、lsの使用と同様にlsを解析してはならないことを述べていますstatdateただし、セットアップが正しくありません。あなたは追加する必要があります--date=$ymdから、dateそれ自体で現在の日に印刷されますが、ここでの目的は、ファイルの日付フォーマットを変換することです
Sergiy Kolodyazhnyy

このls -la | cut -c32-33コマンドは、ファイル名に潜在的な落とし穴があるだけでなく、単にユーザー名の長さとファイルのサイズに依存しているため、完全に信頼できません。このstat -c "%x" *.*コマンドは問題ないように見え*.*ますが、使用することにより、ドットを含むファイル名のみに制限しています。意図は隠しファイルもキャッチすることだったと思います。その場合は、事前にドットファイルのグロビングを有効*にし、*.*次の代わりに使用する必要がありますshopt -s dotglob; stat -c "%x" * | [...]
コス

ああ、Sergが言ったよう--date="$ymd"に、dateコマンドに追加する必要があります。追加しないと、現在の日付が表示されます。
コス

コメントをありがとう。私は問題に対処し、より良い最初の例を提供しました。
ケノーブ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.