すべてのサブフォルダ内のすべてのテキストファイルを1つの巨大なテキストファイルにリンクする

すべてのサブフォルダ内のすべてのテキストファイルを1つの巨大なテキストファイルにリンクする

まあ、状況はすべて同じ名前のプロファイルに従う未知の数のサブディレクトリがあるということです。

フォルダ0、フォルダ1、フォルダ2、フォルダ3など

各フォルダには3つのテキストファイルがあり、これらのテキストファイルはすべてのフォルダに同じ3つのファイル名を持ちます。

ファイル1ファイル2ファイル3

すべてのフォルダ内のすべてのテキストファイルをフォルダ0、ファイル1、ファイル2、ファイル3から始め、すべてのフォルダで同じ順序で1つのテキストファイルにリンクする簡単な方法を見つけたいと思います。

これで、少数のフォルダに対してcatを使用できるようになりました。

cat folder0/file1 folder0/file2 folder0/file3 folder1/file1 folder1/file2 folder1/file3 folder2/file1 folder2/file2 folder2/file3 folder3/file1 folder3/file2 folder3/file3 > textfile

しかし、フォルダの数は不明です。おそらく100個または1000個でしょう。

これを行うことができるスクリプトを知っている人がいます。

答え1

Unixツールとパイプのみを使用する:

find ./ -type f -regex './folder[0-9]+/file[0-9]+' -print0 | sort -zV | xargs --null cat

説明する:

find特定の基準に一致するすべてのファイルを検索する

  1. ./find現在の場所(つまり、作業ディレクトリ)から検索するように指示します。
  2. -type ffindfileというディレクトリがある場合にのみファイルを検索するように指示します。
  3. -regexfindフルパスが指定されたパターンと一致するファイルのみを検索することを示します。この場合、「./folder」の後には、1つ以上の数字、新しいディレクトリ、「file」、1つ以上の数字が続きます。
  4. -print0出力にヌル文字で区切られたファイルを見つけるように指示しますfind。これはファイル名に表示されないことを保証し、ファイル名に改行文字が含まれていても機能します。

sortインポートしたリストを並べ替えます。

  1. デフォルトの改行区切り項目の代わりにヌル文字区切り項目を-zソートするように指示します。sort
  2. 人間が項目を直感的に並べ替えるように、項目を並べ替えるように指示します-V。つまり、中間ではない後に項目を並べ替えます。sortfile11file1file2

xargsインポートされた項目を使用して引数として渡すと、推測できるように、cat異なる--null項目xargsは空白や改行文字ではなくnull文字で区切られます。

答え2

そしてzsh

autoload zargs
zargs -r -- folder<->/file<1-3>(nN) -- cat > hugefile

bash、およびGNUツールの使用:

shopt -s extglob nullglob
print0() { (( $# == 0 )) || printf '%s\0' "$@"; }
 
xargs -r0a <(
  print0 folder+([0123456789])/file[123] | sort -zV
  ) cat > hugefile

その中には+([0123456789])(extglobを含む ksh の高度な glob 演算子の一部を有効にする+(...)) zsh <->(ASCII 10 進数シーケンス) に対応するもの、sort -Vzsh のnglob 修飾子に対応する GNU ( との間ではない後folder10に来るように数値をソートするために使用される) )、glob修飾子の場合は、zshの代わりにGNUを使用してリストを分割します。folder9folder1folder2nullglobNxargszargs引数のリストが長すぎます。間違い。

引数をNULで区切って印刷する関数をprint0定義しました(bashには'sがないためzsh)。ただし、ここではファイルパスにprint -rNC1固有の文字が含まれていないことを考慮して、改行で区切って印刷して無視することをお勧めします。事実:リストが空の場合、その行は無視されるため空白行を印刷します。xargs-0printf '%s\n'xargs

答え3

特定のフォルダ数に達すると、次のことができます。

cat folder*/* > file

または特定のファイル/ディレクトリのみ:

cat {folder1,folder2,folder3}/{file1,file2,file3} > file

名前が固定文字列と連続した数字で構成されている場合は、次のように単純化できます。

cat folder{1..3}/file{1..3} > file

これでファイルやフォルダが多いとこれは失敗しますが、ほとんどの場合は機能します。たとえば、マイコンピュータで次のコマンドを使用して、1000個のディレクトリに3000個のファイルを作成しました。

mkdir folder{1..1000}
touch folder{1..1000}/file{1..3}
for f in */*; do echo "$f" > $f; done

次に、すべてのファイルを1つにリンクします。

cat folder*/* > file

これは3000行を含むファイルを提供します。

ただし、問題が発生した場合はいつでも以下を使用できますfind

find folder1 folder2 folder3 -name "file[123]" -exec cat {} + > file

または

find folder* -name "file[123]" -exec cat {} + > file

警告する:これらの方法のいずれも順序を指定することはできませんが、すべてのディレクトリで同じ順序を持つ必要があります。

関連情報