这是一个简单的格式化问题,但答案让我感到惊讶。
我有一个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”但是它看起来就像第一次尝试的那样。
那么,任何想法如何做这个简单的格式化?谢谢!
答案 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)以获得更好的解释。