将制表符添加到存储在变量中的行的开头

将制表符添加到存储在变量中的行的开头

我正在编写一个脚本,该脚本将处理从客户端收到的 .zip 文件。在我的工作中,通常希望将收到的 .zip 文件的内容列在日志文件中作为验证手段。我已经能够从测试文件中提取文件列表并将文件列表插入日志文件中。

我现在尝试通过在日志文件中提取的文件的名称之前添加换行符和制表符来整理日志文件。我已经最接近评论了下面示例中的行,但它仅将选项卡添加到输出的单行中。我接下来考虑使用 SED,但我对它的了解不足只会导致日志文件中出现空白行......

    log_message "-------- Extracting files"
    zipflist="`unzip -Z1 $file`"
    log_message "Files found in received zip file..."
#    log_message $'\n\t\t\t'"$zipflist"
    log_message `sed '1 s/^/$'\t'"$zipflist"/' `

“log_message”函数将字符串传递到带有前置日期时间的文件。

这是迄今为止我得到的最好结果:

2023-12-29 09:31:44: Files found in received zip file...
2023-12-29 09:31:44:
                        loremipsum.pdf
loremipsum.txt
dummy_report.xml

我希望输出看起来像这样:

2023-12-29 09:31:44: Files found in received zip file...
2023-12-29 09:31:44:
                        loremipsum.pdf
                        loremipsum.txt
                        dummy_report.xml

有没有办法使用 RHEL 中的 SED、tr 或其他基本实用程序来完成此任务?我无法安装任何未经公司批准的东西,所以我更喜欢使用我拥有的东西。 (省去审批的麻烦)

答案1

% str=$'foo\nbar\ndoo\n'
% printf "%s" "$str" |sed -e $'s/^/\t/'
    foo
    bar
    doo

(如果您不打算对列表执行任何其他操作,则unzip | sed无需使用 var 即可直接执行。)

答案2

在 bash shell 中,您可以对存储为元素的行执行此操作大批变量如下。首先,将zipinfo输出读入 shell 数组而不是字符串标量变量,然后使用参数扩展的数组形式${parameter/pattern/string}为每个元素添加前缀。

例如,给定一个简单的日志函数

log_message() { printf '%s\n' "$@"; }

然后

readarray -t zipflist < <(unzip -Z1 "$file")
log_message "${zipflist[@]/#/$'\t'}"

答案3

您可以只使用“此处字符串”:

sed -e $'s/^/\t\t\t/' <<< "$zipflist"

如果文件列表(用换行符分隔它们)已经存在于 shell 变量中,那么这将是合适的。

但是,由于您要从命令将其放入 shell 变量中,因此最好直接在原始命令中进行格式化:

zipflist="$(unzip -Z1 "$file" | sed $'s/^/\t\t\t/')"

然后你会遇到的问题是第一行没有对齐。您可以通过在前面添加换行符来处理该问题,如下所示:

log_message "-------- Extracting files"
zipflist="$(unzip -Z1 "$file" | sed -e $'1i\\\n' -e $'s/^/\t\t\t/g')"
log_message "$zipflist"

这应该准确产生您在问题中指出的所需输出。


一些补充评论:我想知道,这个log_message命令是什么?一般来说,通过清理日志辅助函数的逻辑可能会更好,这样您就可以将内容直接传递给它并让它正确处理它,将时间戳添加到输入的每一行之前,就像日志通常那样。如果这是一个 Linux 系统,您可以使用该logger命令,从而绕过像这样摆弄空格的需要。 logger默认情况下写入系统日志,但您也可以关闭该部分并使用其标准错误。

一个好的后续问题可能是这样的:“有什么干净快速的方法可以在脚本输出的每一行前面加上当前时间戳?” (当然假设你在直接提问之前做了一些功课并做出了一些努力。)

相关内容