私はLinuxに初めてアクセスし、ディレクトリ内のファイルとサブディレクトリのすべての名前(引数として提供されている)を印刷し、それぞれに同じ名前のファイル数を印刷する必要があるシェルスクリプトを書く必要がありました。このディレクトリのファイルです。
私の問題は、すべてのファイルとディレクトリの名前を印刷でき、ジョブの2番目の部分も実行できますが、それらを1つにまとめることができないことです。つまり、私の出力には2つの異なる部分があります。
/some/path
a1
a2
a3
a1 1
a2 1
#a1, a2 files and a3 directory
次のようにする必要があります。
a1 1
a2 1
a3
これはシェルスクリプトの作成に使用するコードです。
#the first part that prints all the names from the directory
mydir=$1
cd $mydir
ls -l $mydir | awk '{print $9}'
#the second part that prints the number of files with the same name for every file
file=$(find $mydir -type f -printf '%f\n' | sort | uniq -c)
echo $file
答え1
「Linux/Shell スクリプティング学習」課題の文脈で、以下を提案します。
mydir=$1
for f in "$mydir"/*
do
printf "%s %d\n" "$f" $(find "$mydir" -name "$f" -print 2>/dev/null | wc -l)
done
スクリプト調整:
cd
ディレクトリを入力ls
する必要はありません。- ファイル名は必要ありません
awk
。そうすることはできますがls
... - 別々に実行すると、別々の出力が
ls ... awk
表示されます。find
find
実行中のジョブが出力を計算するだけであれば、出力を特に印刷する必要はありません。- あなたがするすべてが出力を計算することであれば、出力をソートする必要はありません。
uniq
すべてをキャプチャするために使用する必要はありません。-type f
あなたの課題の中であなたがそれを見つけることを望む場合に備えて、私はそれを取り除く自由を持っていました。目次同じ名前-name "$f"
名前が一致するfind
ファイルのみを追加printf
ファイル名と数を同じ出力ラインに結合するために使用されます。ls
ファイル名を取得するために出力を解析する必要はありません。for f in "$mydir"/*
つまり、*
ファイル名と一致するように拡張されます。
また、ユーザーが以下を提供する場合に備えて、すべての変数の使用法を引用しました"this file"
。
出力に隠されたファイルは表示されません。ドットファイル(隠しファイル)と一致するように拡張子を追加することもできますshopt -s dotglob
。"$mydir"/*
高度な警告として、ユーザーが改行文字を含むファイル名を照会に渡すと、改行文字を含むファイル名が誤って計算されます。