51614


以下の操作をディレクトリ内の特定のファイルだけでなく、全ファイルに同じように適用したい時にどのようなコマンドを書けば良いのかわかりません。  
一応、<https://qiita.com/elzup/items/e839a8c4e815808fb4bc>
などは読んでみたのですが、よくわかりません...。  
教えて頂けると助かります。  
元のファイル(01_hangan_chimatao_iku.txt)はTextディレクトリに入っていて、操作後のファイル(hangan_wakati.txt)はTextと同じ階層にあるWakatiディレクトリ内に作成するようにしたいです。

操作(特定のファイル01_hangan_chimatao_iku.txtに対して)

[code]

    $mecab -Owakati 01_hangan_chimatao_iku.txt -o hangan_wakati.txt
    $nkf -w --overwrite hangan_wakati.txt
    
[/code]


CC BY-SA 4.0
2018-12-29T16:04:56.567
51607
2018-12-30T04:05:45.863
2018-12-29T20:41:56.867
31249
31249
question
linux
linuxで特定のディレクトリ内の全てのファイルに対して同じ操作を適用する方法


僕の場合は行いたい「こと」と、行いたい「対象」を分けて考える手法を良く使います。

行いたいことは、引数として渡されたファイル名に対してどういう事を行うかを、シェルスクリプトに記述して、該当ディレクトリまたは`/usr/local/bin`に実行パーミッションを付けて配置します。

ひな形はこんな感じになります。

[code]

    #!/bin/sh
    
    while [ -n "$1" ]
    do
        fullname=$1
        extension=${fullname##*.}
        filename=${fullname%.*}
        suffix=${filename##*_}
        if [ "$suffix" != "Z" ] ; then
            mv ${filename}"."${extension} ${filename}"_Z."${extension}
        fi
        shift
    done
    
[/code]

今回の場合は`mecab`出力を同じ階層にある`Wakati`ディレクトリに`wakati.txt`という名前で出力することと読めますので、

[code]

    #!/bin/sh
    
    while [ -n "$1" ]
    do
            # 引数をファイル名と拡張子に分割、出力ファイル名作成
        originalpath=`dirname $1`
        fullname=`basename $1`
        extension=${fullname##*.}
        filename=${fullname%.*}
        outputname="$originalpath"/Wakati/"$filename"_wakati.txt
            # 実行したいコマンド
        mecab -Owakati "$fullname" -o "$outputname"
        nkf -w --overwrite "$outputname"
            # 今の引数を捨て、次の引数を処理するためのコマンド
        shift
    done
    
[/code]

これを仮に`domecab`という名前で保存したとして、

[code]

    chmod +x domecab
    sudo mv domecab /usr/local/bin
    rehash
    
[/code]

これで、`domecab`が`unix`コマンドであるかのように使えるようになります。

次に、行いたい対象にこのコマンドを全て適用すればいいわけですが、そのためには、`find`コマンドを使います。  
具体的には、処理をしたい対象テキストファイルがある一つ上のディレクトリーが、`aozora`というディレクトリーだとしましす  
この`aozora`が`ls`で見た場合に`aozora`と見える場合は

[code]

    find aozora -name "*.txt" -exec domecab {} \;
    
[/code]

同様に`.`に見える場合には

[code]

    find . -name "*.txt" - exec domecab {} \;
    
[/code]

と実行すれば`find`の次の引数ディレクトリー以下の`txt`拡張子を持つファイルに対して`domecab`コマンドを実行してくれます。

行いたいことが簡単であれば、`find`コマンドの`-exec`オプションにやりたいことをそのまま書いてしまい、`一行野郎(one
liner)`でやってしまう方が簡単ですが、今回は名前の変更があるため、あえて準備に手間が掛かる代わりに応用が利く方法を紹介させて頂きました。


CC BY-SA 4.0
2018-12-30T04:05:45.863
51614
2018-12-30T04:05:45.863
14745
51607
answer