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を使って"/"を区切り文字としてやってみましたがそれでもうまくいかなかったです。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答2件
0
awkでですが、簡単のために、findでパス名の前に\t
を入れることにして、
Bash
1find $1 -printf "%M %2n %10s %TY-%Tm-%Td %TH:%TM\t%p\n" | 2awk -F'\t' '{n=split($2,a,"/");b=a[n];for(i=n-1;i>0;i--)b=b "/" a[i];print $1,b}'
投稿2016/10/03 13:35
総合スコア84555
0
ベストアンサー
完全に逆から表示であればrevコマンドが使えます。
階層を逆順で表示ですが、良いコマンドが見つからなかったのでawk
修正してみました
bash
1#!/bin/sh 2find /usr/local -printf "%M %n %s %TY-%Tm-%Td %TH:%TM %p\n" | \ 3awk '{for(i=1;i<NF+1;i++){if(i!=NF){if(i==2){printf"%2s",$i}\ 4else if(i==3){printf"%10s",$i}else{printf" %s",$i}}else{n=split($i,ar,"/");\ 5printf" ";while(n>0){printf ar[n] "/";n--}printf "\n"}}}' | \ 6sed -e 's/^ //' -e 's/\/$//'
revを使ってみました
bash
1#!/bin/sh 2find /usr/local/src -printf "%M %2n %10s %TY-%Tm-%Td %TH:%TM %p\n" | while read ff 3do 4echo "$ff" | rev | cut -d\ -f2- | rev | tr '\n' ' ' 5echo $ff | rev | cut -d\ -f1 | rev | awk '{n=split($1,ar,"/");while(n>0){printf ar[n] "/";n--}printf "\n"}' |sed 's/\/$//' 6done
タブをセパレータとして最大長を120としました。
bash
1#!/bin/sh 2find /usr/local -printf "%p\t%M\t%n\t%s\t%TY-%Tm-%Td\t%TH:%TM\n" | \ 3awk -F'\t' '{for(i=1;i<NF+1;i++){if(i!=1){if(i==3){printf"%2d",$i}\ 4else if(i==4){printf"%10s",$i}else{printf" %s",$i}}else{ff="";n=split($i,ar,"/");\ 5while(n>0){ff=ff ar[n] "/";n--};sub("/$","",ff);printf "%-120s",ff}}print""}'
実行環境のLANGをUTF8としています。表示用です。
bash
1#!/bin/sh 2find /home/ts21adm/test -printf "%p\t%M\t%n\t%s\t%TY-%Tm-%Td\t%TH:%TM\n" | nkf -Wsx |\ 3LANG=C awk -F'\t' '{for(i=1;i<NF+1;i++){if(i!=1){if(i==3){printf"%2d",$i}\ 4else if(i==4){printf"%10s",$i}else{printf" %s",$i}}else{ff="";n=split($i,ar,"/");\ 5while(n>0){ff=ff ar[n] "/";n--};sub("/$","",ff);printf "%-80s",ff}}print""}' | nkf -Swx
awkの簡単な説明ですが
awk
1 2awkはsedと同じように入力ファイル1行づつ処理を行います。 3 awk '{....}' <infile >outfile 4 51行のセパレータはデフォルト空白またはタブですそれ以外は-Fにて指定することができます。 6今回はタブだけにしたいので-Fで指定しています。 7 8詳しくは'awk wiki'でググッた方が良いです。分かり易いです。 9今回使ったawkを解説します(分解して) 10 11awk -F'\t' #タブのセパレータ指定 12 13'{for(i=1;i<NF+1;i++){ #NFはタブ区切りのフィールド数 i:フィールドの位置として利用 14 15if(i!=1){ #フィールドの一番目でない行判定 16 17if(i==3){ printf"%2d",$i}\ #3番目のフィールドを2桁で表示 18 19else if(i==4){printf"%10s",$i} #4番目のフィールドを10桁で表示 20 21else{printf" %s",$i}} #1,3,4以外を表示 22 23else{ff="";n=split($i,ar,"/");\ #1フィールド目を"/"で分解して配列arに挿入 24 25while(n>0){ff=ff ar[n] "/";n--} #配列の最後から逆読みで/を加えてffに文字列追加 26 27;sub("/$","",ff); #ff行の最後の余分な/を削除 28 29printf "%-80s",ff} #ffを80桁の右詰で表示 30 31}print""}' #ラインの改行を表示
投稿2016/10/03 03:40
編集2016/10/04 03:37総合スコア4070
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/10/03 04:45
2016/10/03 05:05
2016/10/03 06:17
2016/10/03 06:29
2016/10/03 06:37 編集
2016/10/03 07:18
2016/10/03 10:52
2016/10/03 13:45
2016/10/03 14:18
2016/10/04 00:27
2016/10/04 00:47
2016/10/04 01:28
2016/10/04 02:16
2016/10/04 04:30
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。