Nycto
Nycto

Reputation: 1739

Bash: add column based on command

In Bash, is there a simple way to take a column, run a bash command on the value, then append the result as a new column?

As a simple (and contrived) example, lets say I want a list of symlinks in the current directory and the targets they point to. The awk equivalent might be something like this:

ls | awk '{ "readlink -f "$1 | getline target; print $1, target }'

But that is a mouthful. I would prefer a tool design explicitly for this task. Something akin to xargs:

ls | add-column readlink -f

And the output would be:

A.txt /path/to/A.txt
B.txt /path/to/B.txt

Does such a tool exist?

Upvotes: 0

Views: 167

Answers (2)

redneb
redneb

Reputation: 23880

How about using a simple while loop:

find -mindepth 1 -maxdepth 1 -type l -print0 |
    while IFS= read -r -d '' file; do
        printf "%s\t%s\n" "$file" "$(readlink -- "$file")"
    done | column -t -s $'\t'

Note I am using find instead of ls because it has the -print0 that can handle filename with line breaks. Also, this will not produce the correct output formatting if any symlink or any of their targets contain a tab.

Upvotes: 0

Charles Duffy
Charles Duffy

Reputation: 295696

Easily done, though it's safer for the name to use an underscore rather than a dash (the relevant POSIX standard guarantees only "underscores, digits, and alphabetics from the portable character set" to be supported in function names):

add_column() {
  while IFS= read -r line; do
    printf '%s\t%s\n' "$line" "$("$@" "$line")"
  done
}

ls -1 | add_column readlink -f --

Note that output of ls is not suitable for programmatic use, so this particular example should be just that -- an example -- only.

Upvotes: 1

Related Questions