6

I have a command which outputs a randomly ordered set on words. My goal is, ultimately, to get a sorted list. I'm trying to find a way to do this that can be done with a single command. I know that if the output is on multiple lines, it can be sorted by piping it to sort, such as

$ echo "foo
> bar
> baz" | sort
bar
baz
foo

So is there a simple command that I can use to split a string like "foo bar baz" into separate lines, so I can accomplish my goal with echo "foo bar baz" | magic_string_splitter | sort

edit: bonus, the list actually contains some extra output at the end that would be great to ignore. so for instance, the output of my command might actually be like this

$ print_words
foo bar baz are your words

But I'd still like the final result to just be

bar
baz
foo

We can totally strip off and ignore the "are your words" at the end.

3
  • you can temporarily set IFS to a whitespace Commented Jul 15, 2019 at 18:45
  • According to which criteria can "are your words" be omitted? Commented Jul 15, 2019 at 18:46
  • @Cyrus they are always the last 3 words. so no matter what the randomly output words are, the output will always end with the literal string " are your words" Commented Jul 15, 2019 at 18:47

3 Answers 3

8

You can use tr and (GNU) head:

$ echo "foo bar baz are your words" | tr -s '[:blank:]' '\n' | head -n -3 | sort
bar
baz
foo
  • tr -s '[:blank:]' '\n' squeezes any runs of blanks and replaces them with one linebreak
  • head -n -3 drops the last three lines
Sign up to request clarification or add additional context in comments.

Comments

5

With GNU awk:

echo 'foo bar baz are your words' | awk '{NF-=3; OFS="\n"; $1=$1}1' | sort

NF-=3: Remove last 3 columns from current row.

OFS="\n": set output field separator to newline (or use OFS=ORS).

$1=$1: Forces awk to rebuild current row with new OFS (now newline).

1: awk evaluates 1 as true expression and outputs the current line.

Output:

bar
baz
foo

See: 8 Powerful Awk Built-in Variables – FS, OFS, RS, ORS, NR, NF, FILENAME, FNR

1 Comment

and with any awk: echo '...' | awk '{for (i=1;i<=(NF-3);i++) print $i}' | sort'
1
echo "foo bar   baz more" |tr -s ' ' | cut -d ' ' -f 1-3 | fmt -w 1

The cut selectes the first three fields and the fmt arranges them into separate lines.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.