長さの異なる複数のディレクトリがあるとします。
/tmp/(1) I. First Majuscule Roman Numeral/01. First Arabic Numeral/a. First Grapheme
/tmp/(2) II. Second Majuscule/03. Third Arabic/d. Fourth
解析したいので、出力は次のようになります。
I.01.a.
II.03.d.
awkおよび/またはsedソリューションは何ですか?
答え1
実際にawkやsedは必要ありません。 bashワイルドカードと正規表現テストを使用してください。
for d in /tmp/*/*/*
do
if [[ $d =~ ^/tmp/[^[:space:]]+[[:space:]]([^[:space:]]*).*/([^[:space:]]*).*/([^[:space:]]*) ]]
then
printf "%s\n" "${BASH_REMATCH[1]}${BASH_REMATCH[2]}${BASH_REMATCH[3]}"
fi
done
出力例:
I.01.a.
II.03.d.
内部の正規表現は3つのコンポーネントに分けられます。
^/tmp/[^[:space:]]+[[:space:]]([^[:space:]]*).*/
ファイル名はthen^
で始まり/tmp/
、スペース以外の文字が続く必要があり、その後にスペースが続き、スペース以外の文字(これをキャプチャ)が続く必要があり、スラッシュの前に来るすべての内容が続きます。
([^[:space:]]*).*/
...空白以外の文字が続き(キャプチャ)、スラッシュの前にあるすべての文字
([^[:space:]]*)
...後ろ(空白ではなく文字をキャプチャ) - 後ろに...私たちが気にしないこと。
Bashは、キャプチャされた括弧の順序に従って、これらのキャプチャされたビットをBASH_REMATCH配列に格納します。
答え2
これらは次のとおりです。ただ次のディレクトリ/tmp
:
$ find /tmp -mindepth 3 -type d -print | sed -e 's/\.[^/]*/./g' -e 's/^.* //' -e 's#/##g'
I.01.a.
II.03.d.
このfind
コマンドはレベル 3 ディレクトリを探し、フルパスを出力します。この段階の結果は
/tmp/(1) I. First Majuscule Roman Numeral/01. First Arabic Numeral/a. First Grapheme
/tmp/(2) II. Second Majuscule/03. Third Arabic/d. Fourth
このsed
コマンドは3つのことを行います。
点から次のスラッシュまでのすべてを点に置き換えて生成します。
/tmp/(1) I./01./a. /tmp/(2) II./03./d.
最初のスペースまでビットを削除し、
I./01./a. II./03./d.
スラッシュを削除し、
I.01.a. II.03.d.
答え3
あ、awk
まだ答えがないから…
awk -v FS="" '
{
for (i=1;i<=NF;i++) {
if ($i==" " || $i=="/") {
part=""
} else if ($i==".") {
printf "%s.", part
} else {
part=part FS $i
}
}
}
END { printf "\n" }'
フィールド区切り文字を「」に設定すると、各文字を繰り返すことができます。現在の文字で「」または「/」を探し、見つかったらホルダー(部分変数)をリセットします。 「.」が見つかった場合はホルダーを印刷し、それ以外の場合は現在の文字をホルダーに接続します。完了したら、改行を追加します。
出力例:
I.01.a.
II.03.d.