Bash で正確に 16 行を含むファイルを見つける必要があります。
私の考えは:
find -type f | grep '/^...$/'
find
+grep
またはおそらくfind
+を使用する方法を知っている人はいますawk
か?
それで、
- 一致するファイルを別のディレクトリに移動します。
- 一致しないファイルをすべて削除します。
私はただやります:
wc -l **/* 2>/dev/null | awk '$1=="16"'
私は一緒に行きます
find . -type f | while read f ; do
[[ "${f##*/}" =~ ^.{16}$ ]] && mv "${f}" <any_directory> || rm -f "${f}"
done
また
find . -type f | while read f ; do
[[ $(echo -n "${f##*/}" | wc -c) -eq 16 ]] && mv "${f}" <any_directory> || rm -f "${f}"
done
<any_directory>
実際にファイルを移動するディレクトリに置き換えます。
ところで、find コマンドはサブディレクトリに移動します。これが望ましくない場合は、必要に応じて find コマンドを変更する必要があります。
純粋なbashバージョン:
#!/usr/bin/bash
for f in *; do # Look for files in the present dir
[ ! -f "$f" ] && continue # Skip not simple files
cnt=0
# Count the first 17 lines
while ((cnt<17)) && read x; do ((++cnt)); done<"$f"
if [ $cnt == 16 ] ; then echo "Move '$f'"
else echo "Delete '$f'"
fi
done
このスニペットは作業を行います:
find . -type f -readable -exec bash -c \
'if(( $(grep -m 17 -c "" "$0")==16 )); then echo "file $0 has 16 lines"; else echo "file $0 doesn'"'"'t have 16 lines"; fi' {} \;
したがって、長さが 16 行でないファイルを削除し、長さが 16 行のファイルを folder/my/folder
に移動する必要がある場合は、次のようにします。
find . -type f -readable -exec bash -c \
'if(( $(grep -m 17 -c "" "$0")==16 )); then mv -nv "$0" /my/folder; else rm -v "$0"; fi' {} \;
"$0"
ファイル名に変な記号 (スペースなど) が含まれていても安全であるように、引用符を確認してください。
-v
オプションを使用してrm
andmv
が冗長になるようにしています (何が起こっているのか知りたいです)。-n
オプションは no-clobber です。mv
既存のファイルを上書きしないセキュリティです。古いシステムを使用している場合、このオプションは利用できない場合があります。
この方法の良いところ。変な記号を含むファイル名に関しては、本当に安全です。
悪いこと。見つかったファイルごとにabash
と agrep
とmv
orをフォークします。rm
これは非常に遅くなる可能性があります。これは、よりトリッキーなものを使用して修正できます (ファイル名のおかしな記号に関しては安全なままです)。本当に必要な場合は、可能な限りの回答を差し上げます。ファイルを (再) 移動できない場合にも壊れます。
述べる。-readable
にオプションを使用しているfind
ため、読み取り可能なファイルのみが考慮されます。このオプションがある場合は、それを使用してください。より堅牢なコマンドが得られます!