私のフォルダの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; }'