私はこのコマンドに出くわしました:
ls -l <directory> | tail -n +2 | sed 's/\s\s*/ /g' | cut -d ' ' -f 3 | sort | uniq -c
sed
オプションの\s\s*
の目的を理解しているかどうかは、100%わかりません。
\s
が空白を指していることを知っています。 2番目の\s
は*
の前にあるため、2番目の空白の一致は0回以上発生します。
これは、sed
が入力ストリームからの1つ以上の連続するスペースを単一のスペースに置き換えることを意味しますか?はいの場合、\s+
の代わりに\s\s*
を使用しないのはなぜですか?
\s
は、GNU正規表現のショートカットで、スペースまたはタブ文字に一致するPOSIX式[[:blank:]]
を記述する方法です(\s
は、改行がsed
他の編集コマンドによる)\s
表記は、もともとはPerl正規表現に由来しますが、Perl正規表現では、POSIX式の[[:space:]]
のように機能し、スペース生成文字の幅広い配列と一致します。
コマンド
sed 's/\s\s*/ /g'
1つ以上の連続するスペース/タブを単一のスペースに置き換え、現在の行で一致がなくなるまで置換を繰り返します。
したがって、はい、代わりにs/\s+/g
を使用することもできますが、これは基本的な式ではなく拡張(GNU)正規表現であるため、コマンドに-E
を追加する必要があります。
sed -E 's/\s+/ /g'
現在、これは非標準オプション(-E
)and GNU固有の正規表現(\s
)を使用しています。標準に準拠した方法でコマンドを作成するには、次のいずれかを使用する必要があります
sed 's/[[:blank:]][[:blank:]]*/ /g'
または
sed 's/[[:blank:]]\{1,\}/ /g'
ここで、\{1,\}
は、拡張正規表現修飾子+
および{1,}
( "1つ以上")と同じ意味です。
あなたも使うことができます
tr -s '[:blank:]' ' '
これは同じことをしたでしょう。つまり、すべてのスペースとタブをスペースに変換し、連続するスペースの(-s
)ランを1つのスペースに絞り込みます。
または、そのパイプラインでsed
にtail
の機能を実行させて、
ls -l dir | sed '1d; s/[[:blank:]]\{1,\}/ /g' | cut -d ' ' -f 3 | sort | uniq -c
または、単にawk
を使用します。
ls -l dir | awk 'NR > 1 { count[$3]++ } END { for (user in count) print user, count[user] }'
(awk
を使用すると、スペースを圧迫する必要がありません)