2017-12-01 21 views
0

これは簡単な書式設定の質問ですが、答えが私を逃してしまいます。'ls -lrt'をフォーマットしてbashのテキストファイルに送る方法

ワイルドカードを使用して特定のファイルを検索し、ファイルに出力し、電子メールで送信するためのbashスクリプトがあります。私はls -lrt $var*にする必要がありますが、私はあなたが画面に表示されているように行ごとにきれいに印刷する出力を得ることができません。私は、出力ファイルにこのを探しています:

-rw-rw-r-- 1 user user 14173 Nov 30 06:39 20171129_file1.txt.gz<br> 
-rw-rw-r-- 1 user user 30954 Nov 30 06:39 20171129_file2.txt.gz<br> 
-rw-rw-r-- 1 user user 95933 Nov 30 07:01 20171129_file3.txt.gz<br> 
-rw-rw-r-- 1 user user 399507 Nov 30 08:43 20171129_file4.txt.gz<br> 

私はこの試みた:その後、

-rw-rw-r-- 
1 
user 
user 
133119 
Dec 
1 
07:06 
20171130_filename.txt.gz 
etc...... 

そして:

for f in `ls -ltr $var*`; do 
    echo $f >> /tmp/mailtext 
done 

をしかし、ファイル出力は、すべてのフィールドのための新たなラインを持っています私はechofのような新しい行を送らないprintfでこれを試しましたが、4つのファイルはすべて混乱しています。すべて1行に出力を生成

for f in `ls -ltr $var*`; do 
    printf "x $f" >> /tmp/mailtext 
done 

x -rw-rw-r--x 1x userx userx 13318x Decx 1x 07:06x 20171130_filename1.txt.gzx -rw-rw-r--x 1x userx userx 30793x Decx 1x 07:06x 20171130_filename2.txt.gzx -rw-rw-r--x 1x userx userx 99811x Decx 1x 08:00x 20171130_filename3.txt.gzx -rw-rw-r--x 1x userx userx 41363x Decx 1x 08:10x 20171130_filename4.txt.gz 

は、もちろん私はprintfの「Xの$ fが\ n」を試みたが、それは最初の試みの1のように見えました。

だから、どのようにこの単純な書式設定を行うのですか?ありがとうございました!やって

+3

なぜ 'ls -ltr $ var *>/tmpmailtext'でないのですか?がんばろう。 – shellter

+0

[ls'の出力を解析しないでください](http://mywiki.wooledge.org/ParsingLs)、[コマンド出力の繰り返しに 'for'ループを使用しないでください](http: /mywiki.wooledge.org/BashFAQ/001)。 – chepner

+0

あなたの質問に書式を使用してください。 – PesaThe

答えて

1

あなたがそれらの2回のテストで実現したよう、:

for i in `some command` ; do 
    ... 
done 

は、いくつかのコマンドの出力は$ IFSに従って解析し、単語分割されます、そして私は、一つ一つ、これらの値のそれぞれを取ります。あなたの場合、それはスペースの周りに分割されるので、各単語は1つずつ読み込まれます。私は「$のVAR」の前後に引用符を追加

ls -lrt "$var"* > somefile 

お知らせ(それはほとんどすべての場合には、良い習慣です):あなたが必要なもの

だけで行う、ファイル内のコマンドの出力をリダイレクトするだけですそして、私は*を二重引用符の外側に残して、シェルがまだそれをglobbing要求として解釈するようにしておきます。

あなたの代わりに(間にいくつかのポーズで)線で、結果行を印刷したい場合は、次の操作を行うことができます

for file in "$var"* ; do 
    ls -lrt "$file" # mandatory double-quotes 
    sleep 1   # will sleep 1 second before looping 
done | tee somefile # shows both on your screen AND sends to "somefile" 

またはその任意のバリエーション。

私はlsのの出力解析しませんことをここにお知らせ(exemple用:壊れ方法:ls -lrt "$var"* | whil IFS= read -r line; do ... ; doneは:任意のファイル名に改行が含まれている場合はうまく動作しませんし、他の悪い副作用が同様にあります) 。

代わりに私は正しい方法を直接使用します。forループは、シェルが適切なファイル名を$file varの中に入れるようにします。

参照:良い説明はhttp://mywiki.wooledge.org/BashPitfalls(エントリー1)を参照してください。

+0

ああ、うまくいきました、はい、私はこれを過度にしました!私の守備で 、私は他の誰かのスクリプトを固定して、彼は エコー 'LSの-lrt $するvar *' >> ファイルを持っていたし、それはすべてのごちゃ混ぜました。だから私はそれを解こうとしていた。 とにかく問題は解決しました。私は単純な答えがあることを知っていた! :/ –

+0

@ChuckPedro:試しても恥ずかしいことではありません。あなたはその方法を学びます:)私はあなたがBashPitfallsをすべてブラウズし、BashGuideとBashFaqのエントリも同じサイトで閲覧することをお勧めします。シェルプログラミングへようこそ(また、この場所へ。unix.stackexchange.comは、特にUNIXの下のもの(ファイル名など)に関連するシェル特有の奇妙な場所にも適しています。 –