Bash 函数可以多次缩进管道线,而无需等待整个输入

U. *_*lle 2 linux bash shell scripting

我想要实现的目标:

  • 定义一个可用于管道输入的函数,例如echo input | my_function
  • 该函数修改每个输入行,例如,在开头添加缩进。
  • 该函数可以重复使用两次,在这种情况下会对其进行修改(双缩进)两次,例如echo input | my_function | my_function结果为\t\tinput.
  • 此函数不等待提供完整的输入,它可以直接打印出该行,而无需查看所有输入。

至于我的测试,请看以下脚本:

#!/usr/bin/env bash

main() {
  echo 'first:'
  echo 'once' | tab_indent_to_right
  echo 'twice' | tab_indent_to_right | tab_indent_to_right
  {
    echo 'wait 2 sec'
    sleep 2
    echo 'wait 2 sec'
    sleep 2
    echo 'waited'
  } | tab_indent_to_right
}

tab_indent_to_right() {
  # while read -r line; do echo $'\t'"$line"; done  #  double indent not working
  # awk -v prefix='\t' '{print prefix $0}'          #  buffer not working
  # sed 's/^/\t/'                                   #  buffer not working
  # xargs -I {} echo $'\t{}'                        #  double indent not working
  # xargs -L1 echo $'\t'                            #  double indent not working
}

main
Run Code Online (Sandbox Code Playgroud)

每一行tab_indent_to_right都是我解决问题的失败尝试。他们有两个不同的问题:

  • 双缩进不起作用,例如,tab_indent_to_right | tab_indent_to_right
  • 或者,这些行不会直接刷新/打印,而是被缓冲。换句话说,该函数等待所有sleeps 并立即打印出所有内容,而不是在行出现时打印它们。

如何创建此函数,以便两次调用都能提供我想要的修改,并且脚本不会等待管道 shell 的完全执行?

Cyr*_*rus 6

我建议设置IFS为空以保留空格/制表符。

tab_indent_to_right() {
  while IFS= read -r line; do echo $'\t'"$line"; done
}
Run Code Online (Sandbox Code Playgroud)