アプリ版:「スタンプのみでお礼する」機能のリリースについて

バッチファイルで、指定した数値より小さい数値を含む行を抽出したいのですが、そのような事は可能でしょうか。

環境はWindowsXPです。

例えば、「a.txt」というテキストファイルがあって、以下の様な内容の場合に、「40」以下の数値を含む行を抽出するという事は可能でしょうか。

―――――――――――――――――
【a.txtの内容】
―――――――――――――――――
30
50
70
―――――――――――――――――

使用するコマンドは、WidnowsXP上で動作するものであればなんでも構いません。
何か良い方法をご存知の方がおられましたら、お教え頂けないでしょうか。
何卒、宜しくお願い致します。

A 回答 (5件)

No3です。



がんばれば、バッチだけでも出来そうな気もしますが、時間がかかります。
awkが使えるのであれば、簡単に書けます。

set 入力値=5000
set 入力ファイル=a.txt
awk "{A=$0;if(sub(/^[^0-9]*/,B,A) && sub(/円.*$/,B,A) && A>0 && A<=X)print}" X=%入力値% %入力ファイル% > 結果ファイル.txt
    • good
    • 0
この回答へのお礼

再度、ご回答ありがとうございます。

まさに私が求めていた回答です。ばっちり動作致しました。
本当にありがとうございました。

awkは大変便利ですね。
私のバッチファイルがお恥ずかしいです。

私はまだawkを理解出来ていませんが、是非理解したいです。
勉強して行きます。

ありがとうございました。大変助かりました。

お礼日時:2013/09/18 14:33

具体的なものが書いてないので正確なことは言えませんが、



> Windows標準のコマンドや、sed、grep、awk等を組み合わせて

とのことですが、awkを使えば、sed,grepと同等のことができます。Windowsのコマンドもawkから呼び出すこともできますから、awkのスクリプトだけで、目的のことができるのではないかと思われます。

この回答への補足

無事に目的の処理を達成する事が出来ました。
本当にありがとうございました。

補足日時:2013/09/18 14:40
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。

awkを使えば高度な事が出来ると言うのは、以前他の方にもお教え頂いたのですが、今自分のスキルで、それをマスターしようと思うとかなりの時間が掛かってしましますので、もしコマンド一行で今回の目的の動作が出来るならお教え頂きたかったのです。

awkはスクリプトも組めるのですね。初めて知りました。ありがとうございます。スクリプトも勉強して行こうと思います。

完成したバッチファイルは、質問を投稿した後に自分でもどうにか出来ないかと色々と試して、どうにか完成させたものです。ですので内容はあまり良くないと思います。

具体的なバッチファイルの内容を以下に書きたいと思います。

独学なので、おかしな書き方の箇所もあるかと思いますが、もし良くない箇所があれば指摘して頂けると有り難いです。

処理の内容は、入力ファイルを一行ずつ取り出して調べて行くと行った感じです。

以下のバッチファイルの例では「5000円」以下の記述がある行を抽出するようになっています。

入力ファイルはもう少し複雑なのですが、ある程度簡素化して書いています。

ご回答、本当にありがとうございました。


■ 入力ファイル「a.txt」の内容 

ベルト 900円
シャツ 5000円
ズボン 12000円


■ バッチファイルの内容 

@echo off

rem 一時フォルダの作成
md "TEMP"

rem 「入力値」と「入力ファイル」をセット
set 入力値=5000
set 入力ファイル=a.txt

rem 入力値に「1」を足す
set /a 入力値=%入力値%+1

rem 入力ファイルのコピー
copy "%入力ファイル%" "TEMP\コピーした入力ファイル.txt"

rem カレントディレクトリの移動
cd "TEMP"

rem 空の結果ファイルを作成
copy nul "結果ファイル.txt"

rem ファイルサイズを調べるバッチファイルを作成する
echo set ファイルサイズ=%%~z1> "ファイルサイズを調べる.bat"

rem 再処理する場合はここへ戻る
:再処理

rem 計算結果のリセット
set 計算結果=0

rem コピーした入力ファイルの最初の行を取り出す
awk "NR==1 {print}" "コピーした入力ファイル.txt" > "保存用の行.txt"
awk "NR==1 {print}" "コピーした入力ファイル.txt" > "バッチ用の行.txt"

rem コピーした入力ファイルの最初の行を削除
sed -e "1d" "コピーした入力ファイル.txt" > "一時ファイル.txt"
copy "一時ファイル.txt" "コピーした入力ファイル.txt"

rem 取り出した一行を計算用バッチファイルに置換
sed -e "s/^[^0-9]*\([0-9]\{1,\}\)円.*$/set \/a 計算結果=\1-%入力値%/gi" "バッチ用の行.txt" > "計算.bat"

rem 出来たバッチファイルを実行して計算結果を環境変数にセット
call "計算.bat"

rem 環境変数「計算結果」をファイル出力
echo %計算結果%> "計算結果.txt"

rem 計算結果の出力ファイルに「-」が含まれているか調べる
grep -i "-" "計算結果.txt"
If NOT Errorlevel 1 goto 目的の行が見付かった場合

rem 目的の行が見付からなかった場合は処理を飛ばす
goto 目的の行が見付からなかった場合

rem 目的の行が見付かった場合の処理
:目的の行が見付かった場合

rem 目的の行が見付かった場合は、保存用の行を結合保存する
copy /b "結果ファイル.txt"+"保存用の行.txt" "一時ファイル.txt"
copy "一時ファイル.txt" "結果ファイル.txt"

rem 目的の行が見付からなかった場合はここまで処理を飛ばす
:目的の行が見付からなかった場合

rem コピーした入力ファイルに、まだ行が残っているかチェックする
call "ファイルサイズを調べる.bat" "コピーした入力ファイル.txt"
if '%ファイルサイズ%'=='0' goto コピーした入力ファイルが空になった場合

rem まだコピーした入力ファイルに行が残っていたら再処理する
goto 再処理

rem コピーした入力ファイルが空になった場合は以下の処理を行う
:コピーした入力ファイルが空になった場合

rem 結果ファイルのコピー
copy "結果ファイル.txt" "..\結果ファイル.txt"

rem 処理終了

お礼日時:2013/09/18 12:17

数字だけが書いてあるなら、



for /f %%A in (a.txt) do if %%A leq 40 echo %%A

と簡単。
何文字目から何文字目とか、カンマで区切られているとかなら、さらに処理を追加。

>実際、Windows標準のコマンドや、sed、grep、awk等を組み合わせて、目的の処理は実現出来たのですが、

それを書いて、「もっと簡単にならないか?」という質問にすべきでしたね。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。

forコマンドの例文の件ですが、きちんと動作致しました。お教え頂きありがとうございました。

今回質問させて頂いた経緯は、今回の目的の処理をコマンドで実行出来ないかを検索エンジンで調べ、良い結果を得られなかった為、質問させて頂きました。

完成したバッチファイルは、質問を投稿させて頂いた後に、自分で色々と考えて作ったもので、結局はかなり長いものになってしまっています。

どこを直すかという次元ではなく、私が知らない記述の仕方をしないと、この問題は解決出来ないと思うのです。

私が作成したバッチファイルの内容は、No.4 様のお礼の方に書かせて頂きました。

このバッチファイルでも目的の処理は出来ますが、実際に対象となるデータは、例で挙げたデータよりももっと大きい為、時間短縮の為、少しでも処理を減らしたいのです。

お教え頂いたforコマンドの例も活用して、もっと何かスマートな方法を考えようと思います。

ご回答、本当にありがとうございました。

お礼日時:2013/09/18 12:49

テキストファイルの中身に関して



単純に一行のデータが比較対象の数値のみであれば問題はないけど
数値の前後に文字が入っているような場合だとバッチファイルだけで実現とか難しい

1行の内容が
30・・・40以下なので抽出
50,Abc・・・50は40以上なので抽出除外、しかし5と0は40以下なので抽出
Gto360・・・360は40以上なので除外、しかし6と3と0は40以下なので抽出
Xyz・・・数値が含まれていないので抽出除外

文字列の中に含まれている数値を比較対象とする場合
数値の位置や桁数に規則性がないと、比較することすら出来ない、数値が含まれている行はすべて抽出対象になってしまう
(例えば:先頭から2文字目までが比較対象となる等)

実際のデータ例が質問文にあるa.txtの内容と同じものであれば、行全体が比較対象なので問題はないのだろうけど、実際このデータで40以下の行の抽出なんてやる意味もないだろうから、実データの形式はもっと違った形なんだろうと思う

この回答への補足

無事に目的の処理を達成する事が出来ました。
本当にありがとうございました。

補足日時:2013/09/18 14:40
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。

おっしゃる通りで、実データはもっと多くの文字が含まれています。

実際、Windows標準のコマンドや、sed、grep、awk等を組み合わせて、目的の処理は実現出来たのですが、かなり長い構文になってしまいまして、本当はコマンド一行で出来たらいいのになと思っています。

バッチファイルは、ごく簡単な処理をするにはいいかも知れませんが、複雑な処理をバッチファイルで行おうとすると、かえって難しいのかも知れないですね。

自分は簡単なバッチファイルを書ける程度ですが、プログラミング言語も使えるようにならないと限界があるようですね。これからプログラミング言語も勉強して行こうと思います。

ご回答、本当にありがとうございました。

お礼日時:2013/09/17 20:25

for で 1行ずつ読み取って比較する.

この回答への補足

無事に目的の処理を達成する事が出来ました。
本当にありがとうございました。

補足日時:2013/09/18 14:41
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。

forコマンドは使った事が無いのですが、今から調べてやってみようと思います。

思った動作が出来たらまた書き込もうと思います。

ありがとうございました。

お礼日時:2013/09/17 17:10

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!