

【内容】  
bashにて『キーワードが記載されたリスト（日本語、スペースあり、改行で区切り）』ファイルを参照し、与えた文字列（日本語、スペース・ハイフン等あり）とリストを比較して共通する部分を抽出し、与えた文字列の置換・変更に使いたいです。

【例】  
キーワードが記載されたリスト (hoge_list)

[code]

    東京都　中央区
    東京都　目黒区
    東京都　杉並区
    神奈川県　横浜市
    
[/code]

与える文字列 ($INPUT)

[code]

    "東京都　杉並区　阿佐ヶ谷　1-2-3"
    
[/code]

リスト内のキーワードと共通する部分が東京都 杉並区なので、その部分を抽出し

[code]

    阿佐ヶ谷　1-2-3
    
[/code]

を出力したいです。

よろしくお願いします。


CC BY-SA 4.0
2020-02-11T06:52:49.090
62951
2020-02-16T01:57:08.487
37792
question
linux bash shellscript
bashにてファイル内のキーワードを参照し、文字列と共通する部分を抽出する方法


hoge_list を辞書のように使って、なんとかして一致するものを探してそれを削除… ということをしようとすると、かなり厄介なので、もっと単純に、

  * 文字列の先頭が「東京都 中央区」だったらそれを削除
  * 文字列の先頭が「東京都 目黒区」だったらそれを削除
  * 文字列の先頭が「東京都 杉並区」だったらそれを削除
  * 文字列の先頭が「神奈川県 横浜市」だったらそれを削除

という処理にします。

「一致したら削除」には sed を使うと便利です。

[code]

    s|^東京都　中央区||
    s|^東京都　目黒区||
    s|^東京都　杉並区||
    s|^神奈川県　横浜市||
    
[/code]

という内容のファイルを hoge_list.sed という名前で作成しておき、

[code]

    echo '東京都　杉並区　阿佐ヶ谷　1-2-3' | sed -f hoge_list.sed
    
[/code]

と実行すると、

[code]

    　阿佐ヶ谷　1-2-3
    
[/code]

が得られます。

hoge_list は実際にはかなりの行数があるでしょうから、それを元に hoge_list.sed を作るのも自動化したいですよね。  
その部分も含めてシェルスクリプトにまとめると、以下のようになります。

[code]

    #!/bin/bash
    
    cat hoge_list | sed -e 's/\(.*\)/s|^\1||/' > hoge_list.sed
    
    sed -f hoge_list.sed | sed -e 's/^　//'
    
[/code]

このスクリプトを test.sh という名前で保存し、実行すると、

[code]

    $ echo '東京都　杉並区　阿佐ヶ谷　1-2-3' | ./test.sh
    阿佐ヶ谷　1-2-3
    $ 
    
[/code]

という出力が得られます。


CC BY-SA 4.0
2020-02-11T08:30:18.967
62954
2020-02-11T08:30:18.967
5288
62951
answer


Awk を使ってみました。

[code]

    $ INPUT='東京都　杉並区　阿佐ヶ谷　1-2-3'
    $ awk -vinput="$INPUT" '
        input ~ "^"$0 {
          sub("^"$0"[ \t　]*", "", input)
          exit
        }END{ print input }
      ' hoge_list
    
    阿佐ヶ谷　1-2-3    
    
[/code]


CC BY-SA 4.0
2020-02-11T12:19:05.970
62962
2020-02-11T12:28:01.893
2020-02-11T12:28:01.893
62951
answer


bashの機能だけで実現するなら以下のような感じだと思います。

[code]

    #!/bin/bash
    INPUT="東京都　杉並区　阿佐ヶ谷　1-2-3"
    shopt -s extglob
    list=$(<hoge_list)
    pattern=${list//$'\n'/　|}
    echo ${INPUT#@($pattern)}   
    
[/code]


CC BY-SA 4.0
2020-02-15T02:53:30.453
63061
2020-02-16T01:57:08.487
2020-02-16T01:57:08.487
4388
4388
62951
answer