解決策

解決策

背景:現在、一部のフォルダとその内容から圧縮されたタールボールを生成するアーカイブスクリプトを作成しています。アーカイブを解凍したり、ソースを圧縮したりすることなく、gzipで圧縮されたアーカイブをソースと同期できる必要があります。このために求められる解決策は、のls -l出力をの出力と同期させることですtar -ztvf

どちらのコマンドも同様の出力を返しますが、わずかな違いがあります。ほとんどの違いは正規表現やcut。簡単に解決できない問題の1つは、最大深度でクエリディレクトリに相対的なファイルパスを一覧表示することです。

この問題を克服するために、私は以下を使用して各ファイルを見つけてインポートfindしました。ls

find Webcam -exec ls -lR --time-style="+%Y-%m-%d %H:%M" {} \; | cut -f1,3- -d" " | sed "s/ /\//2" | sed "s/ \+/ /g"

これらのパイプのほとんどはフォーマット用で、find Webcam -exec ls -lR {} \;問題の一部であり、Webcamテストフォルダです。このコマンドの出力は次のとおりです。

-rw-r--r-- debian/debian 162406 2014-04-12 13:42 2014-04-12-134210.jpg
-rw-r--r-- debian/debian 116247 2014-08-09 16:38 2014-08-09-163849.jpg
-rw-r--r-- debian/debian 96597 2015-03-15 19:39 2015-03-15-193905.jpg
-rw-r--r-- debian/debian 100795 2015-04-29 20:23 2015-04-29-202242.jpg
-rw-r--r-- debian/debian 97120 2015-08-02 13:42 2015-08-02-134230.jpg
-rw-r--r-- debian/debian 123835 2015-08-27 23:03 2015-08-27-230306.jpg
-rw-r--r-- debian/debian 97120 2015-08-02 13:42 Webcam/2015-08-02-134230.jpg
-rw-r--r-- debian/debian 100795 2015-04-29 20:23 Webcam/2015-04-29-202242.jpg
-rw-r--r-- debian/debian 116247 2014-08-09 16:38 Webcam/2014-08-09-163849.jpg
-rw-r--r-- debian/debian 96597 2015-03-15 19:39 Webcam/2015-03-15-193905.jpg
-rw-r--r-- debian/debian 162406 2014-04-12 13:42 Webcam/2014-04-12-134210.jpg
-rw-r--r-- debian/debian 123835 2015-08-27 23:03 Webcam/2015-08-27-230306.jpg

これで出力は次のようになりますtar -ztvf

-rw-r--r-- debian/debian 162406 2014-04-12 13:42 Webcam/2014-04-12-134210.jpg
-rw-r--r-- debian/debian 116247 2014-08-09 16:38 Webcam/2014-08-09-163849.jpg
-rw-r--r-- debian/debian 96597 2015-03-15 19:39 Webcam/2015-03-15-193905.jpg
-rw-r--r-- debian/debian 100795 2015-04-29 20:23 Webcam/2015-04-29-202242.jpg
-rw-r--r-- debian/debian 97120 2015-08-02 13:42 Webcam/2015-08-02-134230.jpg
-rw-r--r-- debian/debian 123835 2015-08-27 23:03 Webcam/2015-08-27-230306.jpg

明らかな欠陥は、ls見つかった各項目が2回リストされていることです。一度は必要なパスがあり、もう1つはパスがありません。各項目を2回リストする方法を「修正」しますかls

このエラーの性質(たとえば、後で何が起こっているのか)に関する追加の洞察と、全体的なアーカイブの問題へのより実用的なアプローチを参照してください。しかし、今はこれが挑戦だと考えて解決したいので、主な焦点は限界に合わせる必要がありますls

答え1

問題は、findWebcamもディレクトリを見つけてls Webcamそれを実行すると、そこにあるすべてのファイルが一覧表示されることです。ディレクトリー以外のファイルのみをリストするには、次のように入力します。

-type f

答え2

あなたの質問は、ls -lRすべてのファイル(ファイルを表示する)と各ディレクトリ(ディレクトリの内容を表示する)に対して実行されます。ディレクトリ階層が単純ではなく、サブディレクトリが含まれている場合は、サブディレクトリを再度ナビゲートするのと同じように、コンテンツがより頻繁に表示されます-Rls代わりに、find次のように呼び出す必要があります。

  1. find . -type f -exec ls -l {}、ファイルのみが表示されます。
  2. find . -exec ls -dl {}、ファイルとディレクトリが表示されます。

答え3

この問題の根本原因は非常に短いです(.例:1点)。

理解(ディレクトリを除く)は.fromfindと同じです。find .man find

パスが指定されていない場合は、現在のディレクトリが使用されます。

そして実行すると、生成されたfind .リストにポイントが表示されます
(簡単にするには、名前の異なる4つのファイルを使用するだけです)。

$ find                        ### Works the same with or without the dot.
.
./2014-08-09-163849.jpg
./2014-04-12-134210.jpg
./Webcam
./Webcam/2015-04-29-202242.jpg
./Webcam/2015-08-27-230306.jpg

その後、このリストを(再帰的に)提供しますls -R
ワンクリックですべてのファイルを複製できます。

$ ls -1R .         ### The 1 will make the list 1 column.
.:
Webcam
2014-04-12-134210.jpg
2014-08-09-163849.jpg

./Webcam:
2015-04-29-202242.jpg
2015-08-27-230306.jpg

したがって、すべてのファイルが2回現れるのは当然です(一度はドットで、一度はルックアップで)。

$ find -exec ls -1R {} \;
.:
2014-04-12-134210.jpg
2014-08-09-163849.jpg
Webcam

./Webcam:
2015-04-29-202242.jpg
2015-08-27-230306.jpg
./2014-08-09-163849.jpg
./2014-04-12-134210.jpg
./Webcam:
2015-04-29-202242.jpg
2015-08-27-230306.jpg
./Webcam/2015-04-29-202242.jpg
./Webcam/2015-08-27-230306.jpg

解決策

点を削除します(使用\( ! -name . -prune \) -a)。

find で見つかったファイルのリストからポイントを削除します。

$ find . \( ! -name . -prune \) -a -print
./2014-08-09-163849.jpg
./2014-04-12-134210.jpg
./Webcam

その後、再帰を使用できますls -R

$  find . \( ! -name . -prune \) -a -exec ls -1R {} \;
./2014-08-09-163849.jpg
./2014-04-12-134210.jpg
./Webcam:
2015-04-29-202242.jpg
2015-08-27-230306.jpg

再帰的なlsを避けてください(もっと簡単ですが必須ls -d)。

再帰を使用せずに(ディレクトリに拡張しないオプションls -Rもあります)、ツリーを参照してすべてのファイルを参照します。-dfind

$ find . ! -path . -exec ls -1d {} \;  
./2014-08-09-163849.jpg
./2014-04-12-134210.jpg
./Webcam
./Webcam/2015-04-29-202242.jpg
./Webcam/2015-08-27-230306.jpg    

アーカイブ

もちろん、アーカイブを特定の目的に使用するには、ディレクトリ
名を必要とせず、フルパスファイル名のみを使用する必要があります。

$ find . ! -path ./ -type f -a -exec ls -1R {} \;
./2014-08-09-163849.jpg
./2014-04-12-134210.jpg
./Webcam/2015-04-29-202242.jpg
./Webcam/2015-08-27-230306.jpg

(ポイントではない)についてfind dir

パスを使用している場合、ディレクトリの深さが1より大きい場合、問題は同じです。

これは問題を引き起こさない。

$ find Webcam -exec ls -1R {} \;
Webcam:
2015-04-29-202242.jpg
2015-08-27-230306.jpg
Webcam/2015-04-29-202242.jpg
Webcam/2015-08-27-230306.jpg

ただし、深さを1ずつ増やすと(cd ..)、次のようになります。

$ cd ..
$  find jpg -exec ls -1R {} \;
jpg:
2014-04-12-134210.jpg
2014-08-09-163849.jpg
Webcam

jpg/Webcam:
2015-04-29-202242.jpg
2015-08-27-230306.jpg
jpg/2014-08-09-163849.jpg
jpg/2014-04-12-134210.jpg
jpg/Webcam:
2015-04-29-202242.jpg
2015-08-27-230306.jpg
jpg/Webcam/2015-04-29-202242.jpg
jpg/Webcam/2015-08-27-230306.jpg

以下はトリガされません。

$  find jpg \( ! -path ./jpg -prune \) -exec ls -1R {} \;
jpg:
2014-04-12-134210.jpg
2014-08-09-163849.jpg
Webcam

jpg/Webcam:
2015-04-29-202242.jpg
2015-08-27-230306.jpg

私は2つの再帰ツールを使用していますとても賢くない

より簡単な構造に変更してください。たとえば、find jpg -ls次のようにシェルが提供するリストソリューションを試してみてくださいecho **

$ (shopt -s globstar nullglob; printf '%s\n' jpg/**/*)
jpg/2014-04-12-134210.jpg
jpg/2014-08-09-163849.jpg
jpg/Webcam
jpg/Webcam/2015-04-29-202242.jpg
jpg/Webcam/2015-08-27-230306.jpg

関連情報