パイプで連結された長ったらしいコマンド群を理解するには、個々に分割して出力結果を確認する

yahoo知恵袋で次の質問投稿がありました。

$ cat manpage.txt | awk 'BEGIN{RS="";FS="\n"}{print $1 $2 $3}' | grep -e ' -' | sed -e 's/^ +//g' -e 's/ +/ /g' -e 's/, /,/' -e 's/ /:/' -e 's/ +//g' -e 's/。.*//g' | grep -v '^--' | awk 'BE GIN{FS=":"}{printf "%-29s | %s%s\n",$1,$2,$3}' | sort -f

どのコマンドがどの操作をしているのか動作する順番に教えて欲しいです。

出力結果は以下のリンク先の通りです。
https://scrapbox.io/today-script/sed%2Fawk:_%E3%81%93%E3%82%93%E3%81%AA%E3%81%93%E3%81%A8%E3%81%A7%E3%81%8D%E3%81%9F%E8%87%AA%E6%85%A2

一見、長ったらしくて手に負えられないと思うかもしれないが、1個ずつコマンドを分解すれば、そんなに難しいことはしていない。 以下のように回答しておきました。

コマンドを分解して、各コマンドの出力結果をファイルに出力し、そのファイル内容を確認されてみては如何でしょうか。
例えば、以下のようにコマンドを分解したときに、a.txtとb.txtを比較すれば、b.txtを出力したawkコマンドがどんな処理をしているかイメージがつくと思います。

 1cat manpage.txt > a.txt
 2awk 'BEGIN{RS="";FS="\n"}{print $1 $2 $3}' a.txt > b.txt
 3grep -e ' -' b.txt > c.txt
 4sed -e 's/^ \+//g' c.txt > d.txt
 5sed -e 's/ \+/ /g' d.txt > e.txt
 6sed -e 's/, /,/' e.txt > f.txt
 7sed -e 's/ /:/' f.txt > g.txt
 8sed -e 's/ \+//g' g.txt > h.txt
 9sed -e 's/。.*//g' h.txt > i.txt
10grep -v '^\--' i.txt > j.txt
11awk 'BEGIN{FS=":"}{printf "%-29s | %s%s\n",$1,$2,$3}' j.txt > k.txt
12sort -f k.txt > l.txt

上から順に軽く説明すると、以下のような感じになる。

1行目manpage.txtの内容を出力
2行目\nを区切り文字として分割した時の1〜3列を出力
3行目' -'を含む行を出力
4行目先頭の連続した空白を削除して出力
5行目連続した空白を1個の空白に置換して出力
6行目最初のカンマの直後の空白を削除して出力
7行目最初の空白をコロンに置換して出力
8行目連続した空白を削除して出力
9行目。以降を削除して出力
10行目先頭が--から始まらない行を出力
11行目コロンを区切り文字として分割した時の1〜3列を書式に従って出力(1列目は29桁左寄せ指定)
12行目行を並び替えて出力

※awkの組み込み変数
FS:フィールドの区切り文字(デフォルトはスペース)
RS:レコードの区切り(デフォルトは改行)

※printfの書式は以下リンク先を参照
https://www.seiai.ed.jp/sys/text/csb/chs05/c05b050.html

保守業務でバッチシェルを見ること多々あるが、今回のようにパイプなどで繋がれた長ったらしいコマンドに出くわすこともある。 意図を理解するには、やはり分割して動作を確認することが基本となる。