質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

Q&A

解決済

2回答

1832閲覧

linux ファイルパス表示(逆)

coko1

総合スコア276

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

0グッド

0クリップ

投稿2016/10/03 02:45

編集2016/10/03 04:40

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ページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答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

otn

総合スコア84491

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

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
A.Ichi

総合スコア4070

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

A.Ichi

2016/10/03 03:46

すみませんせっかくのカラム合わせがだめですね。
coko1

2016/10/03 04:45

この形を維持したまま逆順出力できるといいんですが...
A.Ichi

2016/10/03 05:05

find format をまねてawkを修正しました。無理やりですが。
coko1

2016/10/03 06:17

./test.sh: line 21: unexpected EOF while looking for matching `'' ./test.sh: line 22: シンタックス エラー: 期待してないファイルの終了 実行したらエラーになりました。修正前のであれば動いたのですが… sed -e 's/^ //' -e s/\/$//' が21行目に当たります。
A.Ichi

2016/10/03 06:29

大変失礼いたしました。修正しました。
coko1

2016/10/03 06:37 編集

’ が抜けていただけでした! その問題は解決して、期待結果にとても近いものができました。 ですが、もう少し質問してもよいでしょうか? -rwxrwxrwx 1 1100 2015-01-20 11:22 /aaa/bbb/ccc/ddd/eee/001 パスの部分を入れ替えて -rwxrwxrwx 1 1100 2015-01-20 11:22 001/eee/ddd/ccc/bbb/aaa/ とすることはできました。しかし、この場合だとどうすればよいでしょうか? /aaa/bbb/ccc/ddd/eee/001 -rwxrwxrwx 1 1100 2015-01-20 11:22 /aaa/bbb/ccc/ddd/eee/001 のような出力結果だった場合です。(むしろこっちで使いたいのですが…) この表示の時に先頭のパスだけを逆順で出力したいのです。 001/eee/ddd/ccc/bbb/aaa/ -rwxrwxrwx 1 1100 2015-01-20 11:22 /aaa/bbb/ccc/ddd/eee/001 A.Ichiさんの回答を使ってfindのformatの先頭に%pを追加して行ってみた所、 /aaa/bbb/ccc/ddd/eee/001 -rwxrwxrwx 1 1100 2015-01-20 11:22 001/eee/ddd/ccc/bbb/aaa/ のように戦闘が通常通り、後ろ側が逆順となりました。これを逆にしたいです。お願いできないでしょうか。 先端のパスも終端が合うようにスペースで合わせて行いたいです。
A.Ichi

2016/10/03 07:18

別に追加しました先端パスの最大長さの指定は調整して頂けると有り難いです。
coko1

2016/10/03 10:52

少し使ってみたのですが、 権限値の部分が少しおかしく表示される部分がありました。 - 0-rwxrwxrwx 上のような感じで、 "- 0"という意図しないものがついてしまいました…
A.Ichi

2016/10/03 13:45

ファイル名にブランクが入るものが有り、意図しない表示になる様です。空白をセパレータとして処理を行っているので・・・他の方法を思案中です。
A.Ichi

2016/10/03 14:18

セパレータをタブとして修正してみました。
coko1

2016/10/04 00:27

”-0”の問題はなくなりました!ありがとうございます。あとこれはこの処理の問題なのかはわからないのですが、 -rwxrwxrwx     -rwxrwxrwx -rwxrwxrwx のように権限値の部分がずれる行がいくつかあったのですが、原因はわかりますでしょうか?
A.Ichi

2016/10/04 00:47

考えられるのは、最大長の指定よりオーバーした場合と日本語名が有るとずれる事があります。全角を一文字としてカウントしている関係です。後者はファイルの固定位置としては問題無いので表示の仕方で調整可能かを調べています。 otnさんさすがです、全部にTAB入れてました。一応動いたけど
A.Ichi

2016/10/04 01:28

表示用に作成してみました。実行環境の文字コードはUTF8を想定しています。EUCであればnkfのW->E、w->eに変更します。
coko1

2016/10/04 02:16

ありがとうございます!求めたような形に仕上がりました。丁寧に対応していただいて本当にありがとうございます。 お恥ずかし話なのですが、もう一つお聞きしてもよいでしょうか? 私自身awkの知識がなく処理としてどういったことを行っているのかがいまいち掴みづらいのです。ontさんも使っている'\t'が何かとか...今後の参考のために処理の補足、説明をしていただけはしないでしょうか?
coko1

2016/10/04 04:30

何から何までありがとうございます!awkについて調べて少し勉強してみます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問