0

bashで何か特別なことをしたい。for ループと find を使用して部分的な解決策を見つけましたが、より複雑なジョブを作成するスクリプトを作成することを好みます。

次のような複雑なディレクトリ構造があります。

fiction/
 book1/
  chapter1/
   page1.txt
   page2.txt
   ..
  chapter2/
   page5.txt
   page6.txt
  ..
 book2/
  chapter1/
  chapter2/
 ..
non-fiction/
 book5/
  chapter1/
..

要点を理解していただければ幸いです。

要するに、私は次のことをしたいです:

  1. Chapter1 など、各ブックとチャプターを入力します。
  2. /mybooks/book1/chapter1.txt のすべての page1、page2 などを cat します。
  3. 次の章に進み、/mybooks/book1/chapter2.txt について繰り返します。
  4. 次の本に進む

簡単なスクリプトでこれを行うことができました:

for i in */; do cat "$i"*.txt > /newdir/"${i%%/}".txt; done

最初の問題は、章だけでなく、章を含む部分またはサブセクション自体にも分割されている本があることに気付いたときに現れました。唯一の解決策は、これらのフォルダーに cd してスクリプトを手動で実行することでした。

しかし、これはプロのやり方ではありません。サブディレクトリをトラバースしてから戻るようにスクリプトをよりインテリジェントにするにはどうすればよいですか?

4

2 に答える 2

0

この答え...

  • スペースを含むディレクトリを処理する
  • 1 つの章に 9 ページを超えるページがある場合に、ページを正しく並べ替える

これは、次の仮定に基づいています。

  • ページは常にチャプターのすぐ下にあります*
  • ページは page[1 つ以上の数字].txt という名前です
  • パスの「chapter*」に一致する部分は 1 つだけなので、「chapter2/subchapter1」のようなものはありません

#!/bin/bash

while read -r -d $'\0' path; do
    output="$path".txt
    ls -1 "$path"/page*.txt | \
     sed 's/^.*\([0-9][0-9]*\).txt/\1/' | \
     sort -n | \
     while read n; do
         echo "cat ${path}/page${n}.txt >> $output"
         # cat "${path}/page${n}.txt" >> "$output"
     done
done < <(find fiction/ -type d -name "chapter*" -print0)

結果に満足したら、 - 行を削除し、下のecho行のコメントを外します。

例:

find f
f
f/book2
f/book2/chapter1
f/book2/chapter1/page10.txt
f/book2/chapter1/page2.txt
f/book2/chapter1/page1.txt
f/book2/chapter3
f/book2/chapter3/page2.txt
f/book2/chapter3/page1.txt
f/book2/chapter2
f/book2/chapter2/page2.txt
f/book2/chapter2/page1.txt
f/book2/part1
f/book2/part1/subsection1
f/book2/part1/subsection1/chapter1
f/book2/part1/subsection1/chapter1/page2.txt
f/book2/part1/subsection1/chapter1/page3.txt
f/book2/part1/subsection1/chapter1/page1.txt
f/book1
f/book1/chapter1
f/book1/chapter1/page2.txt
f/book1/chapter1/page1.txt
f/book1/chapter3
f/book1/chapter3/page2.txt
f/book1/chapter3/page1.txt
f/book1/chapter2
f/book1/chapter2/page2.txt
f/book1/chapter2/page1.txt
f/book with space
f/book with space/chapter1
f/book with space/chapter1/page2.txt
f/book with space/chapter1/page1.txt

出力:

cat f/book2/chapter1/page1.txt >> f/book2/chapter1.txt
cat f/book2/chapter1/page2.txt >> f/book2/chapter1.txt
cat f/book2/chapter1/page10.txt >> f/book2/chapter1.txt
cat f/book2/chapter3/page1.txt >> f/book2/chapter3.txt
cat f/book2/chapter3/page2.txt >> f/book2/chapter3.txt
cat f/book2/chapter2/page1.txt >> f/book2/chapter2.txt
cat f/book2/chapter2/page2.txt >> f/book2/chapter2.txt
cat f/book2/part1/subsection1/chapter1/page1.txt >> f/book2/part1/subsection1/chapter1.txt
cat f/book2/part1/subsection1/chapter1/page2.txt >> f/book2/part1/subsection1/chapter1.txt
cat f/book2/part1/subsection1/chapter1/page3.txt >> f/book2/part1/subsection1/chapter1.txt
cat f/book1/chapter1/page1.txt >> f/book1/chapter1.txt
cat f/book1/chapter1/page2.txt >> f/book1/chapter1.txt
cat f/book1/chapter3/page1.txt >> f/book1/chapter3.txt
cat f/book1/chapter3/page2.txt >> f/book1/chapter3.txt
cat f/book1/chapter2/page1.txt >> f/book1/chapter2.txt
cat f/book1/chapter2/page2.txt >> f/book1/chapter2.txt
cat f/book with space/chapter1/page1.txt >> f/book with space/chapter1.txt
cat f/book with space/chapter1/page2.txt >> f/book with space/chapter1.txt
于 2012-09-02T21:38:16.500 に答える
0

次のようなものを試すことができます:

for b in */*
do 
  cat $(find "$b" -type f -name \*.txt| sort) >> "$b"/$(basename "$b").txtb
done
于 2012-09-02T20:59:19.720 に答える