たとえば、レポートjpgは、something.jpgと呼ばれるすべてのファイルについて表示されます。これが私の質問を含む私が取り組んでいるコードです。
function report {
x=`ls *.$1`
num=`ls *.$1 | wc -l`
# Question 1:
# Want to use variable for x to get
# num, but num=$($x | wc -l) didn't work for this purpose.
echo There are $num $1 files
if [ $num -lt 10 ]; then
# Question 2:
# for this part, I want to use "find . -name '*.$1'
# with delimiter . to extract filename from its extension
# and display them (Also maybe need to use while or for loop)
fi
}
report jpg
report html
#!/bin/bash
report(){
local -a n=(*.$1)
echo "There are #${#n[@]} files in '$PWD' with extension '$1'."
if (( ${#n[@]} < 10 )); then
find . -maxdepth 1 -type f -name "*.$1" -printf %f\\n | sed -e 's/\.[^.]*$//'
fi
}
report $1
使用法:./script.sh jpg
具体的に質問に答えるには:
Q1。式$x | wc -l
は、「コマンド$x
を実行し、結果をwc -l
にパイプする」ことを意味します。 $x
のcontentsをwc
にパイプするには、num=`echo "$x" | wc -l`
または(bash here string を使用)num=`wc -l <<< "$x"`
を使用できます。
ただし、「バックティック」形式のコマンド置換は非推奨になりました。$( ... )
を使用する習慣を身に付けた方がよいでしょう。
num=$(wc -l <<< "$x")
ファイル名に改行文字(Linuxでは許可されている)が含まれている場合、これは誤ったカウントを与えることに注意してください。
Q2。 find . -name '*.$1'
では、'*.$1'
を囲む単一引用符(別名「ハードクォート」)は$1
の展開を防ぐため、find
は文字どおり$1
で終わるファイル名を検索します。 $1
の早期展開を防ぎながら*.
の展開を許可するには、二重引用符(別名「ソフトクォート」)、つまり"*.$1"
を使用します。
サブディレクトリに降りるのではなく、トップレベルのディレクトリに検索を制限したい場合があります(そうしないと、結果がwc
から取得したカウントと一致しなくなります)。
find . -maxdepth 1 -name "*.$1"
ただし、これが私がやる方法です-bash
シェルを想定:
report() {
shopt -s nullglob
local ext="$1"
set -- *."$ext"
printf 'There are %d %s files' $# "$ext"
if (( $# > 0 && $# < 10 )); then
printf '\t%s\n' "$@"
fi
}
これは Bash Pitfall#1 (シェルグロブを使用する代わりにls
の出力を解析する)を回避し、シェルのset
ビルトインを使用して一致するファイル名を$@
位置に読み取りますパラメータ配列。このように、$#
を使用してファイルの数を明確にカウントできます(たとえ改行が含まれている場合でも、ls
をwc
にパイプすると誤ったカウントが発生します)。 find
コマンドを分離して、一致する名前を繰り返し取得します。
ファイル名なし拡張子を表示する場合は、printf
の$@
を${@%.*}
で置き換えることができます。これにより、配列の各要素から.*
に一致する最も短い末尾の部分文字列を削除します パラメータ展開 。
ファイルの数をテストするために(( ... ))
算術構造を使用することを選択しましたが、必要に応じてPOSIX [ $# -le 10 ]
または[ $# -lt 10 ]
を使用しても何も問題はありません。追加の$# > 0
テストは、指定された拡張子のファイルがない場合に出力をきれいに保つためのものです。
拡張機能の配列を使用することにより、複数の拡張機能を受け入れるように関数を簡単に拡張できます。
function report {
shopt -s nullglob
local exts=( "$@" )
for ext in "${exts[@]}"; do
set -- *."$ext"
printf 'There are %d %s files' $# "$ext"
if (( $# > 0 && $# < 10 )); then
printf ': \n'
printf '\t%s\n' "$@"
else
printf '.\n'
fi
done
}
使用例:
$ report txt jpg foo
There are 71 txt files.
There are 4 jpg files:
b.jpg
foo.jpg
inv_logpolar.jpg
logpolar.jpg
There are 0 foo files.