cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Choose Language Hide Translation Bar
rice_ball
Level II

fileList = Files In Directory(folderPath)で、任意のフォルダから必要なファイルだけ正規表現を用いて選択的に変数に格納したい。

通常、プログラミングでは正規表現などで、ディレクトリの中の任意の文字列を含んだファイルなどを成否表現で引き当てると思います。

しかしながらJMPにおいては、Files In Directory単体では高度なソートができないようです。

ですので、一度変数に格納したものに条件を追加しながら、削り出すような処理を考えていますが、どのような手法がありますでしょうか?

可能なら、複数回の正規表現を用いてファイルをソートしたいと考えています。

 

使用中のJMP:JMP18.2.1

3 ACCEPTED SOLUTIONS

Accepted Solutions

Re: fileList = Files In Directory(folderPath)で、任意のフォルダから必要なファイルだけ正規表現を用いて選択的に変数に格納したい。

Filter Each() is the way to go.  Example to find .png files that contain "2024-06"

 

Names Default To Here( 1 );
files = Files In Directory( Pick Directory( "" ) );
filtered_files = Filter Each( {v, i}, files, Contains( v, "2024-06" ) & Ends With( v, ".png" ) );

 

View solution in original post

jthi
Super User

Re: fileList = Files In Directory(folderPath)で、任意のフォルダから必要なファイルだけ正規表現を用いて選択的に変数に格納したい。

Filter Each() and if you wish to use regex you can combine it with Is Missing().

-Jarmo

View solution in original post

Re: fileList = Files In Directory(folderPath)で、任意のフォルダから必要なファイルだけ正規表現を用いて選択的に変数に格納したい。

SAS Institute Japan株式会社 JMPジャパン事業部 シニアテスターの小野と申します。
すでに回答が出ていますが、念のために簡単な具体例を示しておきます。
 
以下では、RegexおよびFilter Eachを用いて、先頭が「E」で始まり(^E)、かつ、半角数字を含んでおり([0-9])、最後の文字列が".txt"のもの(\.txt$)を取り出しています。
 
files = {"E001.txt", "B002.txt", "EEEEE.txt", "E001.jpg", "E001.txt.jpg", "C001.txt", "EAB1.txt", "1111.txt"};
filtered_files = Filter Each( {v, i}, files,  !Is Missing(Regex(v, "^E(.*)[0-9](.*)\.txt$" )));
同様の処理は、Regexの代わりに、Patで始まる関数でも行えますが、やや指定が長くなるかもしれません。
 
files = {"E001.txt", "B002.txt", "EEEEE.txt", "E001.jpg", "E001.txt.jpg", "C001.txt", "EAB1.txt", "1111.txt"};
filtered_files = Filter Each( {v, i}, files,  
Pat Match(v, Pat Pos(0) + "E" + Pat Arb() + Pat Regex("[0-9]") + Pat Arb() + ".txt" + Pat R Pos(0));
);
Filter Eachの戻り値もリストですので、そこからさらに絞り込むこともできます。
以下では、ファイル名に"001.txt"という文字列を含んでいるものをさらに絞り込んでいます。
 
files = {"E001.txt", "B002.txt", "EEEEE.txt", "E001.jpg", "E001.txt.jpg", "C001.txt", "EAB1.txt", "1111.txt"};
filtered_files = Filter Each( {v, i}, files,  !Is Missing(Regex(v, "^E(.*)[0-9](.*)\.txt$" )));
final_list = Filter Each({v,i}, filtered_files, Contains(v,"001.txt"));

View solution in original post

5 REPLIES 5

Re: fileList = Files In Directory(folderPath)で、任意のフォルダから必要なファイルだけ正規表現を用いて選択的に変数に格納したい。

Filter Each() is the way to go.  Example to find .png files that contain "2024-06"

 

Names Default To Here( 1 );
files = Files In Directory( Pick Directory( "" ) );
filtered_files = Filter Each( {v, i}, files, Contains( v, "2024-06" ) & Ends With( v, ".png" ) );

 

jthi
Super User

Re: fileList = Files In Directory(folderPath)で、任意のフォルダから必要なファイルだけ正規表現を用いて選択的に変数に格納したい。

Filter Each() and if you wish to use regex you can combine it with Is Missing().

-Jarmo

Re: fileList = Files In Directory(folderPath)で、任意のフォルダから必要なファイルだけ正規表現を用いて選択的に変数に格納したい。

SAS Institute Japan株式会社 JMPジャパン事業部 シニアテスターの小野と申します。
すでに回答が出ていますが、念のために簡単な具体例を示しておきます。
 
以下では、RegexおよびFilter Eachを用いて、先頭が「E」で始まり(^E)、かつ、半角数字を含んでおり([0-9])、最後の文字列が".txt"のもの(\.txt$)を取り出しています。
 
files = {"E001.txt", "B002.txt", "EEEEE.txt", "E001.jpg", "E001.txt.jpg", "C001.txt", "EAB1.txt", "1111.txt"};
filtered_files = Filter Each( {v, i}, files,  !Is Missing(Regex(v, "^E(.*)[0-9](.*)\.txt$" )));
同様の処理は、Regexの代わりに、Patで始まる関数でも行えますが、やや指定が長くなるかもしれません。
 
files = {"E001.txt", "B002.txt", "EEEEE.txt", "E001.jpg", "E001.txt.jpg", "C001.txt", "EAB1.txt", "1111.txt"};
filtered_files = Filter Each( {v, i}, files,  
Pat Match(v, Pat Pos(0) + "E" + Pat Arb() + Pat Regex("[0-9]") + Pat Arb() + ".txt" + Pat R Pos(0));
);
Filter Eachの戻り値もリストですので、そこからさらに絞り込むこともできます。
以下では、ファイル名に"001.txt"という文字列を含んでいるものをさらに絞り込んでいます。
 
files = {"E001.txt", "B002.txt", "EEEEE.txt", "E001.jpg", "E001.txt.jpg", "C001.txt", "EAB1.txt", "1111.txt"};
filtered_files = Filter Each( {v, i}, files,  !Is Missing(Regex(v, "^E(.*)[0-9](.*)\.txt$" )));
final_list = Filter Each({v,i}, filtered_files, Contains(v,"001.txt"));
rice_ball
Level II

Re: fileList = Files In Directory(folderPath)で、任意のフォルダから必要なファイルだけ正規表現を用いて選択的に変数に格納したい。

皆様、ご丁寧にご返信いただきありがとうございました。

変数に対する操作は非常に重要ですのに、なかなか理解できず試行錯誤した結果以下のようなコードで完成いたしました。

1,任意のフォルダのパスを読み込ませ、ファイルの一覧をまずは作る

2,CSVのみに絞り込み

3,正規表現を用いて任意の文字を”含まない”ファイルに絞り込み

ただ1点、まだIs Missingの前にある!の意味を理解できずにいます。これは何のために存在しているのでしょうか?

//以下のフォルダにあるファイル一覧を変数に取得する。
files = Files In Directory( "%USERPROFILE%document" );

//絞り込み_CSVファイルである
filtered_files = Filter Each( {v, i}, files,  !Is Missing(Regex(v, "^(.*)[0-9](.*)\.csv$" )));

//with_key_とspec_から始まるファイルを除外する;
list = Filter Each( {v, i}, filtered_files,  !Is Missing(Regex(v, "^(?!.*with_key_|spec_).*$")));
show(list);

Re: fileList = Files In Directory(folderPath)で、任意のフォルダから必要なファイルだけ正規表現を用いて選択的に変数に格納したい。

どうにかご希望の処理が行えてよかったです。
 
エクスクラメーションマーク(びっくりマーク、感嘆符)「!」単体は、後続の式の否定を表す「Not論理演算子」になっています。JMPでの「Not論理演算子」は、1と0を反転させます。(より正確には、JMPでは、0の場合には1、1を含む0以外の場合には0を戻します)。
 
以下のマニュアルに記述があります。
(Google検索する場合には「JMP 演算子 ヘルプ」、JMPヘルプにて検索する場合には「演算子 Not」をキーワードにするとヒットするかもしれません。)
 
また、JMPのプルダウンメニューにおける[ヘルプ]→[スクリプトの索引]では、「Not」で検索するとヒットします(後述するように、「!」演算子には別名の関数としてNot関数が用意されています)。
 
たとえば、以下は1を反転させて0を戻します。
Show(!1);
次は、0を反転させて1を戻します。
Show(!0);
 
この論理演算子「!」が分かりづらい場合には、等価な関数として(別名の関数として)Not関数があります。
Show(Not(1));  // 「!1」と同じ
Show(Not(0));  // 「!0」と同じ
Is Missing関数は、引数が欠測値のときに1を、引数が非欠測値のときに0を戻す関数です。今回はこれら0,1を反転させた値が欲しいので、このNot論理演算子「!」を用いています。
 
以下は、引数が欠測値ですのでIs Missingは0を戻しますが、Not論理演算子「!」によってそれが反転されて1になります。
Show(!Is Missing(""));
以下は、引数が非欠測値ですのでIs MIssingは1を戻しますが、「!」によってそれが反転された0になります。
Show(!Is Missing("Hello, World!"));
 
■余談1
なお、Is Missing関数およびNot論理演算子(「!」)ともに、他の多くの関数や演算子と同様、行列やリストを引数にとることもできます。
x = [15.3, 12.1, ., 13.2, 14.1, .];
Show(!Is Missing(x));
y = {"りんご", "バナナ", "", "みかん"};
Show(!Is Missing(y));
■余談2
!Is Missing(x)が分かりにくい場合には、Is Missing(x)==0 や Is Missing(x)!=1 と指定することもできます。(感嘆符と等号を続けた「!=」は、右辺と左辺が等しくない場合に1を戻し、等しい場合には0を戻します。)
 
Show(Is Missing("")==0);
Show(Is Missing("")!=1);
Show(Is Missing("Hello, World!")==0);
Show(Is Missing("Hello, World!")!=1);
 
■今回、「!」を用いた理由
Filter Each関数は、第3引数の評価値が真(1)となる要素だけを抜き出します。
たとえば、以下は、リストxのうち2より大きな要素だけを抜き出します。
x = {1,5,2,4,3,2,1,4,5,9,1};
y = Filter Each({v,i},x, v > 2);
Show(y);
v>2と逆の要素を抜き出す場合には、v <= 2と指定すればいいだけですが、!(v > 2)と指定することもできます。
x = {1,5,2,4,3,2,1,4,5,9,1};
y = Filter Each({v,i},x, !(v > 2));
Show(y);
!(v > 2)は、vが2よりも大きくない場合(つまり、vが2以下の場合)に「1」を、それ以外では「0」を戻します。
 
■付記
私自身が正則表現に疎いために必ずしも等価な処理とはならないかもしれませんが、また、却ってコードが読みづらくなるかもしれませんが、正則表現を以下のように1つにまとめることはできないでしょうか?(やりたい処理を間違えていたらすみません。)
 

 

files = {
"with_key_001.csv", "spec_001.csv",
"aaa_with_key_001.csv", "aaa_spec_001.csv",
"with_key_001bbb.csv", "spec_001bbb.csv",
"aaa_with_key_001bbb.csv", "aaa_spec_001bbb.csv",
"001.csv", "aaa001.csv", "001bbb.csv", "aaa001bbb.csv",
"001.txt", "aaa001.txt", "001bbb.txt", "aaa001bbb.txt",
"aaa001bbb.csv.txt" }; list = Filter Each( {v, i}, files,  !Is Missing(Regex(v, "^(?!.*with_key_|spec_)(.*)[0-9](.*)\.csv$" ))); show(list);

 

 

Recommended Articles