質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.58%

Linux・Bashでのテキスト処理

解決済

回答 4

投稿 編集

  • 評価
  • クリップ 2
  • VIEW 605

justyum

score 7

こんにちは。Linux初心者です。以前に使われていたLinuxのデバイスを整理しています。
主に、以下の2つのディレクトリ間でのデータのやり取りをしています。

/home/taro/data
/home/taro/scripts

~/data のディレクトリには以下の複数のファイルがあるのですが、欲しい古い情報は、list.txtに入っています。
taro_contact_2020.csv   tomo_picture_2017.jpg   miki_picture_2016.jpg   taro_profile_2018.doc   tomo_profile_2017.doc   taro_profile_2019.doc   list.txt

実際に、以下のコマンドを打つと10個のテキスト情報が表示されます。

cat list.txt


001 taro /data/jane_profile_2011.doc
002 tomo /data/kwood_profile_2010.doc
003 miki /data/pchow_profile_2009.doc
004 tomo /data/janez_profile_2008.doc
005 taro /data/jane_picture_2011.jpg
006 taro /data/kwood_picture2009.jpg
007 miki /data/pchow_picture_2010.jpg
008 taro /data/jane_contact.csv
009 tomo /data/kwood_contact.csv
010 miki /data/pchow_contact.csv

【やりたいこと】
① nano で findtaro.sh というファイルを ~/scripts のディレクトリ内に作って 前述のlist.txt から、 
taro を含むファイル名だけを新しいファイル newfile.txt に挿入したい。 (newfile.txtは~/scriptsに置いています。)
② 念のためにヒットした結果が ~/data のディレクトリに重複して存在しないかテスト・チェックをしておきたい。

【自分でやってみたこと】
以下のコードを書いてみましたが、未熟でコードを完成させることができません。
色々試してみたのですが、newfile.txt に、"..data/list.txt"というテキストが挿入されてしまいます。

for names in ../data/list.txt; do
    grep ' taro ' $names | cut -d ' ' -f3 
    for file in $names; do
        if test -e ~/data/$file; then
            echo "File already exists"; 
        else 
            echo "$file" >> newfile.txt; fi; done

done


どのようなコードを書けば綺麗に処理できるのか、ご教授頂けると幸いです。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

+1

forの機能を勘違いされていると思います。

ちょっと質問文が不明瞭ですが、コードと照らし合わせると、
やりたいのはこういうことではないでしょうか。

awk '$2~/taro/{print $3}' | \
while read line ; do [ -f $line ] && echo $line exists || echo $line >> newfile.txt ; done

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/03/14 18:25

    ご教授頂いた内容を自分で調べることで、新たな知識を得られることができました。
    ありがとうございました。

    キャンセル

+1

KojiDoiさんのアイデアを盗んで

cat ../data/list.txt | grep ' taro ' | cut -d ' ' -f3 | while read line ; do [ -f ..$line ] && echo file $line already exists || echo $line >>newfile.txt


はいかがでしょうか?

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/03/14 18:25

    ご教授頂いた内容を自分で調べることで、新たな知識を得られることができました。
    ありがとうございました。

    キャンセル

checkベストアンサー

0

ちょっとやりたいことが不明瞭ですが、例えば001 taro /data/jane_profile_2011.docの行について、/home/taro/data/jane_profile_2011.docが存在するかチェックして、、、ということなら、

while read num name file
do
  if [ "$name" = taro ]
  then
    if [ -e ~"$file" ]
    then echo "File already exists"
    else echo "$file" >> newfile.txt
    fi
  fi
done < ~/data/list.txt

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/03/14 18:23

    構文の書き方、初心者向けにわかりやすく教授頂きありがとうございました。大変、参考になりました。

    キャンセル

0

やろうとしている事?

  1. taro 行のファイルパスのみ抜き出す。
  2. ファイルパスにファイルが存在していれば何もしない。
  3. ファイルが無ければ、newlist.txt にファイルパスを書き出す。

実装

やり口が悪いが、ループ回すまでもないのでパイプでつなぐだけで出来そう。

grep -E '[[:blank:]]taro[[:blank:]]' list.txt | \
awk '{print $3}' | \
xargs ls  2>&1 | \
grep 'cannot access' | \
cut -d "'" -f 2 > newlist.txt

追伸

やりたいのはデータのコピーだと思われるので、実際には rsync で実現することなのではないでしょうか?

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.58%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る