19

I am trying to make a modular script. I have several scripts/commands which are called from a single script.
I want to prefix the output of each separate command.

Examle:

My files are allcommands.sh / command1.sh / command2.sh

command1.sh outputs
file exists
file moved

command2.sh outputs
file copied
file emptied

allcommands.sh runs the scripts command1.sh and command2.sh

I want to prefix each output of these two scripts like this:
[command1] file exists
[command1] file moved
[command2] file copied
[command2] file emptied

Ivan Dokov
  • 321
  • 1
  • 2
  • 7

3 Answers3

25

I assume that what you are doing in your allcommands.sh is:

command1.sh
command2.sh

Just relace it with

command1.sh | sed "s/^/[command1] /"
command2.sh | sed "s/^/[command2] /"
j_kubik
  • 423
11

A minimal example of allcommands.sh:

#!/bin/bash
for i in command{1,2}.sh; do
    ./"$i" | sed 's/^/['"${i%.sh}"'] /'
done

With command1.sh and command2.sh executable and in the same directory just echoing the wanted strings, this gives the shell output:

$ ./command1.sh 
file exists
file moved
$ ./command2.sh 
file copied
file emptied
$ ./allcommands.sh 
[command1] file exists
[command1] file moved
[command2] file copied
[command2] file emptied

Quick sed breakdown

sed 's/^/['"${i%.sh}"'] /'
  • s/ enters "regexp pattern match and replace" mode
  • ^/ means "match the beginning of every line"
  • ${i%.sh} happens in the shell context and means "$i, but strip the suffix .sh"
  • ['"${i%.sh}"'] / at first prints a [, then exits the quoted context to grab the $i variable from the shell, then re-enters to finish with the ] and a space.
0

Simple example:

#!/usr/bin/env bash
# allcommands.sh

output-prefix() { local title="${1/.[a-zA-Z.0-9-_]/}" title="${title/[.-/_a-zA-Z0-9]//}" "$@"
2> >(sed "s/^/[$title] [ERR] /" >&2)
> >(sed "s/^/[$title] [INF] /") }

output-prefix ./command1.sh

[command1] [INF] file exists

[command1] [INF] file moved

output-prefix ./command2.sh

[command2] [INF] file copied

[command2] [INF] file emptied

Prefix with a timestamp as a function/script:

#!/usr/bin/env bash

output-prefix() { local title="$1" ; shift "$@"
2> >(sed "s/^/$(date '+%Y-%m-%d %H:%M:%S') [ERR] {$title} /" >&2)
> >(sed "s/^/$(date '+%Y-%m-%d %H:%M:%S') [INF] {$title} /") }

output-prefix command1 ./command1.sh arg1

2023-04-29 17:37:12 [INF] {command1} arg1

2023-04-29 17:37:12 [ERR] {command1} test as errout

output-prefix command2 ./command2.sh argB

2023-04-29 17:37:12 [INF] {command2} argB

2023-04-29 17:37:12 [ERR] {command2} argB as errout