如何格式化'ls -lrt'并发送到bash中的文本文件

时间:2017-12-01 18:47:51

标签: bash format printf echo ls

这是一个简单的格式化问题,但答案让我感到惊讶。

我有一个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>

我试过了:

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

但文件输出为每个字段都有一个新行:

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

然后我尝试使用printf,它不会发送像echo这样的新行,但这四个文件都混杂在一起。

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 个答案:

答案 0 :(得分:1)

正如您通过这两项测试所做的那样:

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

根据$ IFS对某些命令的输出进行解析和字分割,然后逐个获取每个值。在您的情况下,它将在空格中分开,因此每个单词都是逐个读取的。

您需要的只是将命令的输出重定向到文件中,只需执行以下操作:

ls -lrt "$var"* > somefile

请注意,我在&#34; $ var&#34;周围添加引号(在几乎所有情况下,这都是一个很好的做法),并且我将*留在那些双引号之外,以便shell仍然将其解释为全局请求。

如果您想要逐行打印结果(中间有一些暂停),您可以执行以下操作:

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的输出(例如:已损坏方式:ls -lrt "$var"* | whil IFS= read -r line; do ... ; done:如果包含任何文件名,则效果不佳换行,还有其他不良副作用)。

相反,我直接使用正确的方法:for循环让shell将相关文件名一个接一个地放在$file var中。

请参阅:http://mywiki.wooledge.org/BashPitfalls(条目1)以获得更好的解释。