サイズが10MB未満のmp4ファイルを含むすべてのディレクトリを繰り返し検索しようとしています。
要件は、
- ディレクトリにはmp4ファイルが1つしかありません。
- mp4ファイルは10MBを超えることはできません。
私が使用するコマンドは
% find . -type f -name "*.mp4" -size -10M | cut -d/ -f2 | sort | uniq -c | grep "^ 1"
何が起こっているのかわかりませんが、このコマンドは正確な結果を返しません。
さらなる調査は、次のコマンドが機能することを示しました。
find . -type 'f' -name "*.mp4" -printf '%h\n' | sort | uniq -c | grep -E "\s+1\s"| cut -c 9-
ところでミックスに追加してみると、-size -10000000c
そのファイルに10MB未満のmp4ファイルが1つあり、10MBを超える他のmp4ファイルもあることがわかりました。私の言うことは、私が言及したコマンドは、サイズが10MBを超えるmp4ファイルを考慮していないということです。この質問は2段階に分けることができると思います。
mp4ファイルを含むすべてのディレクトリを探します。これは上記のコマンドで行われます。
ファイルが10MB未満であることを確認してください。
次のコマンドを使用して、ディレクトリ内の単一のmp4ファイルのファイルサイズを取得できます。
find . -type 'f' -name "*.mp4" -printf '%h\n' | sort | uniq -c | grep -E "\s+1\s" | cut -c 9-| xargs -I {} -n 1 /usr/bin/du -a "{}" | grep -v ".mp4$"
ベストアンサー1
find
少なくともGNUの場合、-size -10M
これは次のメガバイトに丸められたサイズが10未満(つまり9以下)のファイルの場合に当てはまります。
サイズ9 x 1024 x 1024 + 1 = 9437185バイトのファイルは10MiBに丸められ、10未満ではないため選択されません。
10MB(1MBは1,000,000バイト、1メビバイト== 1,048,576バイトと混同しないでください)より厳しく小さく、サイズが0〜9,999,999のファイルの場合は、以下を使用してください。
find . -size -10000000c
10MiBより厳密に小さいファイルの場合、サイズ範囲は0から10485759です。
find . -size -10485760c
これで、GNUシステムでこれらのファイルの1つだけを含むディレクトリを取得するには、次の手順を実行できます。
LC_ALL=C find . -name '*.mp4' -type f -size -10000000c -printf '%h\0' |
LC_ALL=C sort -z |
LC_ALL=C uniq -zu |
tr '\0' '\n'
どこ
find
h
これらのファイルのead(ディレクトリ名)をNULで区切って印刷します(現在のロケールで有効なテキストでなくても、LC_ALL=C
他の方法で終わるすべてのファイル名が報告されます)。.mp4
sort
これをソートしますuniq
(LC_ALL=C
ファイル名がロケールで有効なテキストではない問題、および文字が完全に定義されている順序ではない問題を回避するためにもう一度)。uniq -zu
一意の項目のみが報告されます。
NULはファイルパスには現れない唯一の文字なので、ファイルのリストはNULで区切られて渡されます。私たちはこれらのNULを人が使用できるように改行文字に変換しますtr
。
を使用すると、zsh
次の操作も実行できます。
print -rC1 -- **/*(NFe['()(( $# == 1 )) $REPLY/*.mp4(N.L-10000000Y2)'])
どこ:
print -rC1 --
print
それはolumnr
の議論です。1
C
**/
サブディレクトリの数に制限はありません。*(NF...)
任意のファイル名(隠しファイルを除く)ですが、、、N
...F
glob修飾子でさらにe
限定されます。N
:nullglob
不一致の場合はエラーを返すのではなく、nullに拡張するようにこのglobを有効にします。F
:すべてのディレクトリ(F
およびを除いて1つ以上のエントリを含むディレクトリ)を選択します。.
..
e[code]
:成功したファイルを選択してくださいcode
。() {body} arguments
複数のパラメータを持つ匿名関数。- 返された算術評価
{body}
です。(( $# == 1 ))
本物この匿名関数のパラメーター数が1の場合。 $REPLY
内部には、code
検討中のファイル(ここではディレクトリ)へのパスがあります。*.mp4(qualifiers)
: (隠されていない)mp4
ファイルはさらに制限されます。.
:一般ファイルのみ(例:find
's'-type f
)L-10000000
:ファイルサイズは10MBより厳密に小さい。Y2
:2つのファイルを見つけて最適化を停止します。
.
(現在の作業ディレクトリ自体)は考慮されません。これを考慮したい場合**/*
はに変更してください{.,**/*}
。
ここで明確に説明したように、mp4ファイルが1つしか含まれていないディレクトリを探し、そのファイルが通常のファイル(ディレクトリ、シンボリックリンクではありません...)で、サイズが10 MB未満(たとえばを含むディレクトリを除く):5 MBと15 MB mp4ファイル(サイズに関係なく、複数のmp4があるため、10 MB未満のmp4ファイルが1つしかありませんが)、まだ次のようになりますzsh
。
print -rC1 -- **/*(NFe['
() {
(( $# == 1 )) && ()(($#)) $1(N.L-10000000)
} $REPLY/*.mp4(NY2)
'])
GNUfind
とGNU awk
(またはNULで区切られたレコードを処理できるawk)の場合は、次のようになります。
LC_ALL=C find . -name '*.mp4' -printf '%h\0%s\0%y\0' |
awk -v RS='\0' '
{
getline size; getline type
total[$0]++
if (size < 10e6 && type == "f") found[$0]++
}
END {for (dir in found) if (total[dir] == 1) print dir}'