【问题标题】:Bash write ls error to fileBash 将 ls 错误写入文件
【发布时间】:2016-05-06 21:08:49
【问题描述】:

我有一个文件夹,其中包含许多以连续编号和一些文本命名的文件,但缺少一些编号。我想将所有缺失的数字写入一个文件。

这是我目前得到的:

#!/bin/bash
for (( c=23457; c<=24913; c++ ))
do
  files=$(printf %q kassensystem/documents/"${c}")
  ret=$(ls $files*)
  echo "$ret" >> ./out.log
done

输出如下:

所有现有文件都写入文件,所有错误都写入控制台。我想要完全相反的方式。将所有错误 (ls: ..file not found) 写入文件!

我尝试使用完整的命令ls $files* | grep -v 'kasse*',但是我只得到一个空行的文件。

感谢您的帮助!

【问题讨论】:

  • 错误信息发送到stderr,你只是在捕获stdout
  • ls 不应该用于这种情况。请参阅mywiki.wooledge.org/ParsingLs——shell 本身可以扩展 glob 以填充名称列表,因此无需调用主要为人类生成输出的外部工具。
  • 顺便说一句,将&gt;&gt;out.txt 放在一个循环中效率非常低 - 每次执行该行时它都会重新打开文件
  • ...另一方面,当您生成要替换为字符串的文本时,使用printf %q 是一种很好的做法,该字符串将被解析为shell命令(通过eval "ls $files*",或ssh "$host" "ls $files*",或sh -c "ls $files*",或诸如此类),但是当变量的内容上没有发生这样的shell解析时,就不需要(实际上,适得其反)。 ls $files 等不带引号的扩展仅执行字符串拆分和全局扩展,它不处理 printf %q 可能创建的退格或引号。

标签: linux bash file output ls


【解决方案1】:
exec 4>out.log  # open output file just once, not once per write

for (( c=23457; c<=24913; c++ )); do
  files=( kassensystem/documents/"$c"* ) # glob into an array
  [[ -e $files ]] || echo "$c" >&4       # log if first file in array doesn't exist
done

【讨论】:

  • 我认为这个解决方案更好。另外我只将数字而不是整个 stderr 写入文件
猜你喜欢
  • 2015-12-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-16
  • 1970-01-01
  • 2018-06-14
  • 1970-01-01
相关资源
最近更新 更多