(BASIC)ファイルから文字列を抽出する

(BASIC)ファイルから文字列を抽出する

文字列からすべての文字列を抽出しようとしています(表示される順序で)。タイパンBASIC発売"ただし、一部の文字列の末尾にスペースがあり、それを「見て」計算できる必要があるため、出力に区切り文字(文字列の始まりと終わり)が表示されるようにしたいです。最後は"この時点で緩和されます)。

悪いことに、私はmacOSで動作しているので、いくつかのgrepパラメータはGNUgrepとは異なります。

2つの文字列を含む行の例は次のとおりです。

1270 VTAB 19:PRINT " WE'VE CAPTURED A BIGGER SHIP!" : GOSUB 760:VTAB 19:PRINT " WE'RE TRANSFERRING TO IT NOW.": GOSUB 780:G = G + INT ( RND (1) * (G + 1)) + 1:E = SH + INT ( RND (1) * (SH + 150)) + 1: SH = SH + E:MW = MW + E:P=0

私が必要とする出力は

...
" WE'VE CAPTURED A BIGGER SHIP!"
" WE'RE TRANSFERRING TO IT NOW."
...

"私はusing 1を含む行だけを得ました。

grep -o '".*"'

しかし、これは貪欲なgrepであり、1行に複数の文字列を取得し、複数の文の行の個々の文字列を別の行に出力するのではなく、文字列間の文字列ではないコマンドもキャプチャします。

" WE'VE CAPTURED A BIGGER SHIP!" : GOSUB 760:PRINT TAB(0,18) " WE'RE TRANSFERRING TO IT NOW."

これは明らかに私が望むものではありません。

次のnon-greedyはgrep正しく動作しないようで、何らかの理由で出力に少ない行を提供します。それはおそらくそのgrepオプションがmacOSで利用できないからです-P

grep -oP '".*?"'

とにかく出力を続けてgrep -o '".*"'入力しawkて見つけたらでもフィールド3

grep -o '".*"' TAIPAN_BAS.txt | awk -F\" '{print $2}'
grep -o '".*"' TAIPAN_BAS.txt | awk -F\" '{print $4}'
grep -o '".*"' TAIPAN_BAS.txt | awk -F\" '{print $6}'

複数ステートメント行の2番目(または3番目または後続)の文字列が出力されることを除いて、多少の結果が得られます。その後文字列の最初の項目がすべてリストされます。

たとえば、これを入力として使用します。

1270 VTAB 19:PRINT " WE'VE CAPTURED A BIGGER SHIP!" : GOSUB 760:VTAB 19:PRINT " WE'RE TRANSFERRING TO IT NOW.": GOSUB 780:G = G + INT ( RND (1) * (G + 1)) + 1:E = SH + INT ( RND (1) * (SH + 150)) + 1: SH = SH + E:MW = MW + E:P=0
1280 IF SR < .1 THEN 1300 
1281 IF P > 0 THEN 1050 
1285 REM ARRIVAL (1290)
1290 CR = 0: SR = 1:L=PO:V(L) = V(L) + 1: B=0:K=0:GOSUB 160:HOME:PRINT:INVERSE:PRINT A$;: NORMAL: PRINT " ARRIVING "; L$(L);" AFTER": PRINT " A VOYAGE OF ";ET;" DAYS.": INVERSE:PRINT A$:NORMAL: GOSUB 780: HOME:GOTO 120

出力されますn番目「一括」の文字列:

<first command output>
 WE'VE CAPTURED A BIGGER SHIP!
 ARRIVING 
<second command output>
 WE'RE TRANSFERRING TO IT NOW.
 AFTER
<third command output>
 A VOYAGE OF 

このようにソートすると、出力が良くなります。

 WE'VE CAPTURED A BIGGER SHIP!
 WE'RE TRANSFERRING TO IT NOW.
 ARRIVING 
 AFTER
 A VOYAGE OF 

しかし、これらの「より理想的な」出力にはまだ2つの問題があります。

  • 最後の文字列(" DAYS.")がありません。一つ必要です。追加8番目のフィールドを取得するコマンドは次のとおりです。

    grep -o '".*"' TAIPAN_BAS.txt | awk -F\" '{print $8}'
    
  • 二重引用符もありません。

これが私が見たいものです(使用:二重引用符。みんな文字列の長さと表示順序):

" WE'VE CAPTURED A BIGGER SHIP!"
" WE'RE TRANSFERRING TO IT NOW."
" ARRIVING "
" AFTER"
" A VOYAGE OF "
" DAYS."

ノート:アポストロフィを除いて、文字列には引用符(一重引用符または二重引用符)は含まれません。

私の質問は次のとおりです

  • どうやって見つけることができますか?みんな発行する必要なしに複数ステートメント行のフィールドまで分離コマンドは{print $2 $4 $6 ...}フィールド - プログラムで表現する方法はありませんかawk
  • バッチ(最初の文字列のすべての項目、2番目の文字列のすべての項目、3番目の文字列のすべての項目など)ではなく、順番に表示されるように2番目と3番目の文字列をファイルにリンクするにはどうすればよいですか?
    • 私はこれを試しました

      grep -o '".*"' TAIPAN_BAS.txt | awk -F\" '{printf $2,"\\n"$4"\\n"$6}'
      

      ただし、すべてが1行に出力され、最初の文字列インスタンスのみが出力され、改行(\\n)は無視されるように見えます。

  • awkフィールド区切り記号(例:)の削除を停止するにはどうすればよいですか"

今回も私はmacOSを使用しているので、GNUソリューションは役に立たないかもしれません。また、私はそのようなものを喜んで使用しますsed(私はそれを試しましたが、cut彼らはtrそれを取り除き"、多くのコードを残しました)。


1からこの回答到着コマンド出力から引用符付き文字列の内容を抽出する方法は?

2回再確認すると、「使用済み」メッセージのみが表示されます。

3からこの回答到着二重引用符間の文字列の抽出

ベストアンサー1

使用幸せ(以前のPerl_6)

~$ raku -ne '.put for .comb( / \" <-["]>+? \" /);'  file

または:

~$ raku -ne '.put for .comb( / \" ~ \" <-["]>+?  /);'  file

以下は、Perlシリーズのプログラミング言語であるRakuで書いた答えです。 Rakuには、コード解析のための強力な正規表現/構文エンジンがあります(参照:「Raku文法の簡単なパーサー」)。

上記のコードでcomb目的のパターンを検索できます。カスタム文字クラスを生成するには、<+["]>肯定と<-["]>否定の選択に関する引用符を見つけます。 2番目の答えは、Rakuの~チルダ表記を使用しています。これは、入れ子になったテキスト要素および/または周辺要素を抽出するのに役立ちます。

入力例:

1270 VTAB 19:PRINT " WE'VE CAPTURED A BIGGER SHIP!" : GOSUB 760:VTAB 19:PRINT " WE'RE TRANSFERRING TO IT NOW.": GOSUB 780:G = G + INT ( RND (1) * (G + 1)) + 1:E = SH + INT ( RND (1) * (SH + 150)) + 1: SH = SH + E:MW = MW + E:P=0
1280 IF SR < .1 THEN 1300 
1281 IF P > 0 THEN 1050 
1285 REM ARRIVAL (1290)
1290 CR = 0: SR = 1:L=PO:V(L) = V(L) + 1: B=0:K=0:GOSUB 160:HOME:PRINT:INVERSE:PRINT A$;: NORMAL: PRINT " ARRIVING "; L$(L);" AFTER": PRINT " A VOYAGE OF ";ET;" DAYS.": INVERSE:PRINT A$:NORMAL: GOSUB 780: HOME:GOTO 120

1295 REM THAT'S ALL FOLKS (1300-1321)
1300 HOME:NW = C - D:Q = NW / GT: VTAB 4: INVERSE: PRINT A$;: NORMAL: PRINT:PRINT "YOUR SCORE, BASED UPON TIME AND YOUR": PRINT "NET WORTH (EXCLUDING STOCK) IS ";: GOSUB 1330:INVERSE: PRINT A$: NORMAL
1310 IF X$ = "R" THEN PRINT "WOULD YOU LIKE TO PICK UP THIS":PRINT"GAME WHERE YOU LEFT OFF (Y/N)?": GOSUB 60:IF X$ = "Y" THEN HOME:GOTO 120
1320 GOSUB 1340: VTAB 10:PRINT A$;: PRINT "DO YOU WISH TO START OVER (Y/N)?": GOSUB 60:IF X$ = "Y" THEN RUN
1321 END

出力例:

" WE'VE CAPTURED A BIGGER SHIP!"
" WE'RE TRANSFERRING TO IT NOW."
" ARRIVING "
" AFTER"
" A VOYAGE OF "
" DAYS."
"YOUR SCORE, BASED UPON TIME AND YOUR"
"NET WORTH (EXCLUDING STOCK) IS "
"R"
"WOULD YOU LIKE TO PICK UP THIS"
"GAME WHERE YOU LEFT OFF (Y/N)?"
"Y"
"DO YOU WISH TO START OVER (Y/N)?"
"Y"

上記の出力例は起動用です。引用符付き文字列が見つかった行番号を記録することもできます。

~$ raku -e ' for lines.kv -> $k,$v { put "$k\t$_" for $v.comb( / \" <-["]>+? \" /)};' file
0   " WE'VE CAPTURED A BIGGER SHIP!"
0   " WE'RE TRANSFERRING TO IT NOW."
4   " ARRIVING "
4   " AFTER"
4   " A VOYAGE OF "
4   " DAYS."
7   "YOUR SCORE, BASED UPON TIME AND YOUR"
7   "NET WORTH (EXCLUDING STOCK) IS "
8   "R"
8   "WOULD YOU LIKE TO PICK UP THIS"
8   "GAME WHERE YOU LEFT OFF (Y/N)?"
8   "Y"
9   "DO YOU WISH TO START OVER (Y/N)?"
9   "Y"

grep最後に、「プログラム行番号」を返したい場合は、Rakuがエラーを引き起こす空白行をフィルタリングするので、大きな助けになります。

~$ raku -e 'for lines.grep(*.chars).map( *.split(" ", 2)) { my $k = .[0];  my $v = .[1];  put "$k\t$_" for $v.comb( / \" <-["]>+? \" /) };'  file
1270    " WE'VE CAPTURED A BIGGER SHIP!"
1270    " WE'RE TRANSFERRING TO IT NOW."
1290    " ARRIVING "
1290    " AFTER"
1290    " A VOYAGE OF "
1290    " DAYS."
1300    "YOUR SCORE, BASED UPON TIME AND YOUR"
1300    "NET WORTH (EXCLUDING STOCK) IS "
1310    "R"
1310    "WOULD YOU LIKE TO PICK UP THIS"
1310    "GAME WHERE YOU LEFT OFF (Y/N)?"
1310    "Y"
1320    "DO YOU WISH TO START OVER (Y/N)?"
1320    "Y"

https://docs.raku.org/言語/regexes#Tilde_for_nesting_structs
https://docs.raku.org/言語/regexes
https://docs.raku.org
https://raku.org

おすすめ記事