If I have really long output from a command (single line) but I know I only want the first [x] (let’s say 8) characters of the output, what’s the easiest way to get that? There aren’t any delimiters.
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
One way is to use cut:
command | cut -c1-8
This will give you the first 8 characters of each line of output. Since cut is part of POSIX, it is likely to be on most Unices.
Method 2
These are some other ways to get only first 8 characters.
command | head -c8
command | awk '{print substr($0,1,8);exit}'
command | sed 's/^(........).*/1/;q'
And if you have bash
var=$(command)
echo ${var:0:8}
Method 3
Another one liner solution by using parameter expansion
echo ${word:0:x}
EG: word="Hello world"
echo ${word:0:3} or echo ${word::3}
o/p: Hel
EG.2: word="Hello world"
echo ${word:1:3}
o/p: ell
Method 4
If you have a sufficiently advanced shell (for example, the following will work in Bash, not sure about dash), you can do:
read -n8 -d$'' -r <(command)
After executing read ... <(command), your characters will be in the shell variable REPLY. Type help read to learn about other options.
Explanation: the -n8 argument to read says that we want up to 8 characters. The -d$'' says read until a null, rather than to a newline. This way the read will continue for 8 characters even if one of the earlier characters is a newline (but not if its a null). An alternative to -n8 -d$'' is to use -N8, which reads for exactly 8 characters or until the stdin reaches EOF. No delimiter is honored. That probably fits your needs better, but I don’t know offhand how many shells have a read that honors -N as opposed to honoring -n and -d. Continuing with the explanation: -r says ignore -escapes, so that, for example, we treat \ as two characters, rather than as a single .
Finally, we do read ... <(command) rather than command | read ... because in the second form, the read is executed in a subshell which is then immediately exited, losing the information you just read.
Another option is to do all your processing inside the subshell. For example:
$ echo abcdefghijklm | { read -n8 -d$'' -r; printf "REPLY=<%s>n" "$REPLY"; }
REPLY=<abcdefgh>
Method 5
This is portable:
a="$(command)" # Get the output of the command.
b="????" # as many ? as characters are needed.
echo ${a%"${a#${b}}"} # select that many chars from $a
To build a string of variable length of characters has its own question here.
Method 6
I had this problem when manually generating checksum files in maven repository.
Unfortunately cut -c always prints out a newline at the end of output.
To suppress that I use xxd:
command | xxd -l$BYTES | xxd -r
It outputs exactly $BYTES bytes, unless the command‘s output is shorter, then exactly that output.
Method 7
How to consider Unicode + UTF-8
Let’s do a quick test for those interested in Unicode characters rather than just bytes. Each character of áéíóú (acute accented vowels) is made up of two bytes in UTF-8. With:
printf 'áéíóú' | LC_CTYPE=en_US.UTF-8 awk '{print substr($0,1,3);exit}'
printf 'áéíóú' | LC_CTYPE=C awk '{print substr($0,1,3);exit}'
printf 'áéíóú' | LC_CTYPE=en_US.UTF-8 head -c3
echo
printf 'áéíóú' | LC_CTYPE=C head -c3
we get:
áéí á á á
so we see that only awk + LC_CTYPE=en_US.UTF-8 considered the UTF-8 characters. The other approaches took only three bytes. We can confirm that with:
printf 'áéíóú' | LC_CTYPE=C head -c3 | hd
which gives:
00000000 c3 a1 c3 |...| 00000003
and the c3 by itself is trash, and does not show up on the terminal, so we saw only á.
awk + LC_CTYPE=en_US.UTF-8 actually returns 6 bytes however.
We could also have equivalently tested with:
printf 'xc3xa1xc3xa9xc3xadxc3xb3xc3xba' | LC_CTYPE=en_US.UTF-8 awk '{print substr($0,1,3);exit}'
and if you want a general parameter:
n=3
printf 'áéíóú' | LC_CTYPE=en_US.UTF-8 awk "{print substr($0,1,$n);exit}"
Question more specific about Unicode + UTF-8: https://superuser.com/questions/450303/unix-tool-to-output-first-n-characters-in-an-utf-8-encoded-file
Tested on Ubuntu 21.04.
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0