web-dev-qa-db-ja.com

awk '{print $ 9}'最後のls -l列にファイル名にスペースが含まれている

一部のファイルにスペースが含まれている場合、awkでファイル名全体をls -lに出力するにはどうすればよいですか。通常、次のコマンドを実行できます。

ls -l | awk '{print $9}'

ファイルにスペースがある場合、これは機能しません。 $ 9、$ 10、$ 11などをどうにかして印刷することは可能ですか?

16
Mint

より良い解決策:そもそもls出力を解析しようとしないでください。

Irc.freenode.org #bashチャネルの公式wikiに、これが悪いアイデアである理由と、代わりに利用できる代替アプローチの説明があります: http:// mywiki。 wooledge.org/ParsingLs

Find、 stat 、および同様のツールを使用すると、落とし穴なしで探している機能が提供されます(すべてが明らかではありません-いくつかは、異なるls実装のプラットフォームに移動するときにのみ発生します)。

特定の例として、現在のディレクトリでファイルのみを検索しようとしていると思います(ディレクトリは検索しないでください)。 ls -lを使用した現在の実装は、+ tまたはsetuid権限を持つファイルを除外するため、バグがあります。これを実装する正しい方法は次のとおりです。

find . -maxdepth 1 -type f -printf '%f\n'
34
Charles Duffy

完成のために。 sedでも実行できます。

# just an exercise in regex matching ...
ls -l | sed -E  -e '1d; s/^([^ ]+ +){8}//' 
3
mikk

それでも、検索や他のツールの代わりにls -lを要求する場合、これが私の解決策です。それはきれいで破壊的ではありません:

  1. Forループを介して$ 1 .. $ 8を ""に設定して破棄します
  2. それは$ 9の前にたくさんのスペースを残し、sub()コマンドを使用してそれらを削除します
  3. 残りを印刷する
ls -l | awk '{for (i = 1; i < 9; i++) $i = ""; sub(/^ */, ""); print}'
2
Hai Vu

どういうわけかフィールドを組み合わせることを含むより良いアプローチがあるでしょう、しかし:

 $ echo 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ... | 
 awk '{for(i = 9; i <= NF; i ++)printf "%s"、$ i}' 
 9 10 11 12 13 14 ... 

printf "%s " $iを使用すると、改行ではなくi番目のフィールドの後にスペースが付けられて印刷されます。 forループは、フィールド9から最後のフィールドに移動するように指示するだけです。

2
Mark Rushakoff
ls -l | awk -v x=9 '{print $x}'

私は問題なくディレクトリのファイル名を取得するためにこれを使用します。私は、ファイルの種類がわからない場合は問題がなく、問題のない検索ソリューションを見つけました。ls-lが何を表示しているのかわかっている場合は、デフォルトでアルファベット順に並べ替えます。

1
user5453829

解決策は、sedを使用してWordまたは文字でスペースをエンコードおよびデコードすることです。

ls -l | sed s/\ /{space}/ | awk '{print $9}' | sed s/{space}/\ /

これは、awkに渡す前に、行内のすべてのスペースを{space}で置き換えます。行がawkに渡された後、{space}をスペースに戻します。

他の人が述べたfindの方がはるかに優れたソリューションです。しかし、本当にawkを使用する必要がある場合は、これを試すことができます。

1
Pithikos
echo 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 | 
  awk 'BEGIN {OFS=ORS=""} ; {for (i=9;i<NF;i++) print $i " "; print $NF "\n"}'
1
Amro