web-dev-qa-db-ja.com

コマンドの各出力行の接頭辞と接尾辞の文字列

Bashスクリプトを記述しようとして問題が発生しました。 grepが出力すると、(通常)多くの行が返されます。これらの出力行のそれぞれに文字列のプレフィックスとサフィックスを付けたいと思います。

また、次のようにlsgrepにパイプしていることにも注意してください。

ls | grep
18
SpecialBomb

Sedを使用:

ls | grep txt | sed 's/.*/prefix&suffix/'
30
Cyrus

sedの場合:

ls | grep pattern | sed -e 's/^/prefix/' -e 's/$/suffix/'

ただし、これには改行のあるファイル名の問題、およびlsの解析に関するさまざまな問題があり、これは一般に悪い考えです。

Perlを使用

Perl -e 'print "prefix".$_."suffix\n" for grep { m/somepattern/} glob "*"'

注-Perlのgrepは、grepコマンドのようにパターンをとることができますが、ファイルテストの適用なども実行できます。

例えば。

grep {-d} glob "*" #filters directories.
grep { (stat)[9] > time() - 60 } glob "*" #reads file mtime and compares. 

grep内では、デフォルトのイテレータ$_が現在の要素の値に設定されているため、sed/grepスタイルの正規表現を適用したり、さまざまなタスクに基づいて実行したりできます。 $_.

5
Sobrique

この場合、GNU findを使用すると、これらすべてを一度に実行できるため、lsのパイプと潜在的に面倒な解析が不要になります。

find . -maxdepth 1 -name '[^.]*' \
  -regextype posix-extended -regex "MYPATTERN" \
  -printf 'SOMEPREFIX %f SOMESUFFIX\n'

(もちろん、findは他のコマンドの出力を任意に変更する良い方法ではありません!)

いくつかのメモ:

  • -maxdepth 1および-name [^.]*名前の一致をプレーンなls(またはls .)。シェルスタイルのグロブを使用できますが、「*」は先頭の「。」と一致することに注意してください。名前で bashとは異なり、[^.]*は、がない頭に「。」がないものを意味します。
  • MYPATTERNは適切なPOSIX EREです(デフォルトのタイプはEmacsです。 こちら を参照)、butこれは、ファイル名全体なので、.*thing.*だけではなくthing
  • おそらく-name/-regex両方ではなく(例:-regex "[^。]。MYPATTERN。"
  • -printfは、 たくさんのものをサポートしています%nは、修飾されていないファイルまたはディレクトリの名前です

 (ただし、これはfindのバージョンによって異なる場合があります。manページの「STANDARDS CONFORMANCE」セクションを確認してください)

外部プログラムを必要としない可能な代替手段として、bashにはcompgenがあり、これはとりわけ、オプションなしのlsと同等のグロブを展開します。

compgen -P "someprefix>" -S "<somesuffix" -G "pattern"

これは、改行を含む空白を含むファイル名を処理します。 compgen -G "*"は、プレーンなlsと同じ出力を提供する必要があります(ただし、ls *はまったく別のものです)。それでもgrepが必要です。これで問題が解決する場合と解決しない場合がありますが、言及する価値はあります。

2
mr.spuratic

sedおよびfindソリューションは、プレフィックス/サフィックスに正規表現のキー文字が含まれている場合、または(即時値の代わりに)環境変数を渡したい場合、xargs + echoの方が適切かもしれません。

環境変数あり:

ls | grep p | xargs -I % sh -c "echo $PATH/%"

インラインで:

ls | grep p | xargs -I % sh -c "echo `pwd`/%"
0
lashgar