質問: findの結果を表示する際にフォーマットを指定しています。 フォーマット:"%M %2n %10s %TY-%Tm-%Td %TH:%TM %p\n" 表示例:-rwxrwxrwx 1 1100 2015-01-20 11:22 /aaa/bbb/ccc/ddd/eee/001 ファイルの権限値や、サイズタイムスタンプ等を表示するフォーマットになっています。 その中の%pでファイルパスを表示させているのですが、ファイルパスを逆順で表示させることは可能でしょうか? /aaa/bbb/ccc/ddd/eee/001 上記のパスを 001/eee/ddd/ccc/bbb/aaa/ ("階層を逆順で表示) or 100/eee/ddd/ccc/bbb/aaa/ (完全に逆から表示) 希望としては上の出力結果にしたいですが、二通りのどちらかでも構いません。逆順出力させるにはどうしたらよいでしょうか? revコマンドで行うと表示例のすべてが逆から表示されてしまいました。ファイルパスのみを逆順で表示させたかったのですが... tacコマンドでオプション -sを使って"/"を区切り文字としてやってみましたがそれでもうまくいかなかったです。
回答: 完全に逆から表示であればrevコマンドが使えます。 階層を逆順で表示ですが、良いコマンドが見つからなかったのでawk 修正してみました ``` #!/bin/sh find /usr/local -printf "%M %n %s %TY-%Tm-%Td %TH:%TM %p\n" | \ awk '{for(i=1;i0){printf ar[n] "/";n--}printf "\n"}}}' | \ sed -e 's/^ //' -e 's/\/$//' ``` revを使ってみました ``` #!/bin/sh find /usr/local/src -printf "%M %2n %10s %TY-%Tm-%Td %TH:%TM %p\n" | while read ff do echo "$ff" | rev | cut -d\ -f2- | rev | tr '\n' ' ' echo $ff | rev | cut -d\ -f1 | rev | awk '{n=split($1,ar,"/");while(n>0){printf ar[n] "/";n--}printf "\n"}' |sed 's/\/$//' done ``` タブをセパレータとして最大長を120としました。 ``` #!/bin/sh find /usr/local -printf "%p\t%M\t%n\t%s\t%TY-%Tm-%Td\t%TH:%TM\n" | \ awk -F'\t' '{for(i=1;i0){ff=ff ar[n] "/";n--};sub("/$","",ff);printf "%-120s",ff}}print""}' ``` 実行環境のLANGをUTF8としています。表示用です。 ``` #!/bin/sh find /home/ts21adm/test -printf "%p\t%M\t%n\t%s\t%TY-%Tm-%Td\t%TH:%TM\n" | nkf -Wsx |\ LANG=C awk -F'\t' '{for(i=1;i0){ff=ff ar[n] "/";n--};sub("/$","",ff);printf "%-80s",ff}}print""}' | nkf -Swx ``` awkの簡単な説明ですが ``` awkはsedと同じように入力ファイル1行づつ処理を行います。 awk '{....}' outfile 1行のセパレータはデフォルト空白またはタブですそれ以外は-Fにて指定することができます。 今回はタブだけにしたいので-Fで指定しています。 詳しくは'awk wiki'でググッた方が良いです。分かり易いです。 今回使ったawkを解説します(分解して) awk -F'\t' #タブのセパレータ指定 '{for(i=1;i0){ff=ff ar[n] "/";n--} #配列の最後から逆読みで/を加えてffに文字列追加 ;sub("/$","",ff); #ff行の最後の余分な/を削除 printf "%-80s",ff} #ffを80桁の右詰で表示 }print""}' #ラインの改行を表示 ```