2017-08-26 11 views
0

Linux lsバイナリに渡されるコマンドライン引数(特殊な"[email protected]" Bash変数に含まれています)のリストを解析しようとしています。任意の位置で引数リストから位置パス引数をBashの "ls"に抽出します。

引数は任意に-h又は--color又は--hide 'pattern'等キーワード引数を含んでいてもよく、それらは必要に応じてディレクトリまたはファイルパスを含んでいてもよい(絶対/home、相対./binまたは暗黙的に相対Documents)。

リストから位置パス引数のみが抽出される方法はありますか?

すべてのエッジケースを除外することは合理的に不可能な場合は、行の最後の引数として与えられたときに、少なくとも目標を達成し、パス引数を抽出できますか?

場合、それは私が("show git branch in ls -l" on Ask Ubuntuに関連して)各ラインにさらに情報を追加することによって、ls -alFの出力を修正するための次のステップでawkで、さらにパス引数を処理しようと思って、コンテキストのために役立ちます。ここで私は問題が発生します。 ls -alF /homeの場合、出力に./../というエントリがあり、awkは現在の作業ディレクトリへの相対パスとして処理され、指定された/homeでは処理されません。


実際のスクリプト(Bashの機能は)のUbuntuを掲載しに上記のリンクの答えに記載されています。

lg(){ 
    ls -alF "[email protected]" | 
    awk '{ 
     # Split into columns 1-8 and 9+ (file name): 
     match($0, /^(\S+\s+){8}(.+)$/, f); 
     # do something with the file name using an external command 
     # result is stored in b, e.g. "(master)" or an empty string 
     b=f[2]; 
     print $0, b 
    }' 
; } 

出力例(外部コールが含まれ、元の関数の):ここでは、外部gitコマンドを呼び出すと、その出力の解析スキップ最小限のバージョンである今

$ lg 
total 48 
drwxrwxr-x 12 bytecommander bytecommander 4096 Aug 26 14:48 ./ 
drwxr-xr-x 74 bytecommander bytecommander 4096 Aug 26 15:30 ../ 
drwxrwxr-x 6 bytecommander bytecommander 4096 Aug 26 14:43 git1/ (master) 
drwxrwxr-x 7 bytecommander bytecommander 4096 Aug 26 14:42 git2/ (develop) 
drwxrwxr-x 4 bytecommander bytecommander 4096 Aug 26 14:45 no-git/ 
-rw-rw-r-- 1 bytecommander bytecommander 0 Aug 26 14:42 regular-file 

があれば、私の現在の作業ディレクトリは例えばですgit1(これはリポジトリ)のもので、lg /homeのように実行すると、./の出力はlsに正しく対応しますが、私が追加したリポジトリ情報は正しく現在の作業ディレクトリの1つです。つまりです。親ディレクトリエントリと同じ../

+0

実際に何をしようとしていますか? 'ls'の出力を使って作業するのは、まずは悪い考えです。 – chepner

+0

@chepner私の最終目標は最後の段落で説明されていると思います。私が達成したいのは 'ls -alF'の出力をそのまま出力し、gitメタ情報を出力にリストされているすべてのディレクトリに追加することでそれを拡張することです。私は '.' /' ..'エントリが作業ディレクトリに関連して扱われ、オプションで指定された場所引数には扱われないという問題を現在持っています。そして、はい、私は 'ls'の解析は最善のことではないことを知っていますが、代わりに' ls'を書き直すことです。 –

+0

'myscript -alF/home'のように呼ばれ、' ls "$ @" 'を内部的に呼び出すスクリプトを書こうとしていますが、あなたはスクリプト呼び出し' awk '...'/home'の中にいたいでしょうか?もしawkの呼び出しが 'awk '...' $ {!#} ''であれば、それはあなたが望むものですか?そうでない場合は、具体的なサンプルスクリプトとサンプル入力の期待出力、つまり[mcve]で質問を明確にしてください。 –

答えて

1

もしPerlでOKなら、引数を解析するためにGetopt :: Longパッケージを使うことをお勧めします。ここではサンプルです:

#!/usr/bin/perl 
use Getopt::Long; 

my @args = @ARGV; 

GetOptions(
    'a'   => \$opt{'a'}, 
    'all'   => \$opt{'all'}, 
    'A'   => \$opt{'A'}, 
    'almost-all' => \$opt{'almost-all'}, 
    'author'  => \$opt{'author'}, 
    'b'   => \$opt{'b'}, 
    'escape'  => \$opt{'escape'}, 
    'block-size=s' => \$opt{'block-size'}, 
    # ... 
    'version'  => \$opt{'version'} 
) 
or die "Invalid options: @args\n"; 

my @fileargs = @ARGV; 
print "ls args: @args\n"; 
print "file args: @fileargs\n"; 

たとえばperl script.pl -a --author file1 file2についてls args: -a --author file1 file2file args: file1 file2を印刷します。ファイルの引数を処理するコードを追加することができます。

相対パス名の問題については、ls fileordirの代わりにfind -maxdepth 1 fileordirを実行して絶対パスを取得することをお勧めします。

+0

可能なすべてのパラメータをどこか先に設定せずに、位置パス引数だけを取得して他のものを無視することはできますか? –

+0

lsは ' - (\ w | - \ w +(= \ w +)?)'の形式の引数だけを知っているので、 '-'で始まるものは全て削除できますが、 ? – yacc

1

として私の最高の推測では、これまでのところ、あなたが呼び出したいスクリプト「にMyScript」を書いているされています

myscript -<ls-args> <path> 

とのMyScript内部が行います

ls "[email protected]" 
awk 'stuff' "${!#}" 

それは何ではない場合探してあなたの質問を編集して明確にする。

+0

'' $ {!#} ''はここで何をしますか? –

+0

'$#'は 'myscript'に渡される引数の数です。' $ {!#} 'は' myscript'に最後に渡されたargの値です。 –

関連する問題