名前に指定された入力日付以下の日付値を含むファイルを取得します。

名前に指定された入力日付以下の日付値を含むファイルを取得します。

私のフォルダの1つに次の形式のファイルが含まれています。

3_20150412104422154033.txt
3_2015041211022775012.txt
3_20150412160410171639.txt
3_20150412160815638933.txt
3_20150413161046573097.txt
3_20150413161818852312.txt
3_20150413163054600311.txt
3_20150413163514489159.txt
3_2015041321292659391.txt
3_20150414124528747462.txt
3_20150414125110440425.txt
3_20150414134437706174.txt
3_20150415085045179056.txt
3_20150415100637970281.txt
3_20150415101749513872.txt

日付値が入力日付値以下であるファイルを検索したいと思います。

たとえば、「3_20150414」(3_YYYYMMDD)と入力すると、出力がファイル名になることを望みます。

3_20150412104422154033.txt
3_2015041211022775012.txt
3_20150412160410171639.txt
3_20150412160815638933.txt
3_20150413161046573097.txt
3_20150413161818852312.txt
3_20150413163054600311.txt
3_20150413163514489159.txt
3_2015041321292659391.txt
3_20150414124528747462.txt
3_20150414125110440425.txt
3_20150414134437706174.txt

次のコマンドを実行してファイルを一覧表示できます。

ls -l | grep '20150413\|20150414' |awk '{print $NF}'

しかし、私は一つを見つけようとしています。<=マッチ。

答え1

awk文字列比較演算子で、およびを使用できます。

ls | awk '$0 < "3_20150415"'

変数から:

max=3_20150414 export max
ls | LC_ALL=C awk '$0 <= ENVIRON["max"] "z"'

ここで「z」を連結すると、比較は文字列比較であり、ロケール内の数字がC前にソートされるため、1日中いつでも許可されますz

では、zsh次のこともできます。

print -rC1 -- *.txt(e['[[ $REPLY < ${max}z ]]'])

答え2

grepいいえ≤演算子それ自体しかし、それを欺く不器用な方法があります。 0年(または1年の最初の年)と20150414の間のすべての日付が必要です。 (BC日付がテーブルにないと仮定します。)この範囲を正規表現と一致する可能性があるサブ範囲に分割します。

  • 0年から1999年まで - すべての年は0または1で始まるので、grep for [01]
    (すべての正規表現は、「3_」の直後の行の先頭に固定されていると仮定します。)
  • 2000〜2009 - 正規表現200
  • 2010〜2014 - 正規表現201[0-4]
  • 2015年1~3月 - 20150[1-3]
  • 2015年4月1日から9日まで—2014040
  • 2015年第4月10~14日—2014041[0-4]

それから一緒にクリーンアップします。

grep -E '3_([01]|200|201[0-4]|20150[1-3]|2015040|2015041[0-4])'

ls -lもちろん、不要なファイルに関する情報(モード、所有者、修正時間など)をたくさん知らせるので削除してawk '{print $NF}'ファイル名だけを保持してもよい。これは非効率的でエラーが発生しやすいです(ファイル名にスペースやタブが含まれていると中断されます)。の出力を解析することは決して良い考えではlsありませんが、少し簡単にしてより安全にすることができます。不要な情報や不要な情報を取得せずに捨てる必要はありません。

ls | grep -E '3_([01]|200|201[0-4]|20150[1-3]|2015040|2015041[0-4])'

十分に良いでしょう。

しかし、6つの部分からなる正規表現を書くのは面倒でエラーが発生しやすく、スクリプトを書くのは難しいです(不可能ではありませんが)。よりきれいなアプローチは次のとおりです。

ls | awk 'substr($1, 3, 8) <= 20150414'

次に、3番目の位置(つまり、「3_」の後)から始まる8つの文字を抽出し、20150414と2つの8桁の数字と比較します。

答え3

あなたの例を使って考えられる解決策は次のとおりです。

ls -l | grep '3_2015' | awk -v d='3_20150414' '{ s = substr($NF, 1, 10); if (length(s) == 10 && s <= d) print $NF; }'

grepパターンを少し変更し、awk文字列を比較して必要なものを出力するパラメータに検索値を渡しました。
なぜしてはいけないのかについての記事もたくさんあります。分析するlsだから私はいくつかの変更を与えてfindを使用します。

find . -type f -name '*3_2015*' -printf "%f\n" | awk -v d='3_20150414' '{ s = substr($NF, 1, 10); if (length(s) == 10 && s <= d) print $NF; }'

関連情報