What linux shell command returns a part of a string?
Solution 1
If you are looking for a shell utility to do something like that, you can use the cut
command.
To take your example, try:
echo "abcdefg" | cut -c3-5
which yields
cde
Where -cN-M
tells the cut command to return columns N
to M
, inclusive.
Solution 2
From the bash manpage:
${parameter:offset}
${parameter:offset:length}
Substring Expansion. Expands to up to length characters of
parameter starting at the character specified by offset.
[...]
Or, if you are not sure of having bash
, consider using cut
.
Solution 3
In "pure" bash you have many tools for (sub)string manipulation, mainly, but not exclusively in parameter expansion :
${parameter//substring/replacement}
${parameter##remove_matching_prefix}
${parameter%%remove_matching_suffix}
Indexed substring expansion (special behaviours with negative offsets, and, in newer Bashes, negative lengths):
${parameter:offset}
${parameter:offset:length}
${parameter:offset:length}
And of course, the much useful expansions that operate on whether the parameter is null:
${parameter:+use this if param is NOT null}
${parameter:-use this if param is null}
${parameter:=use this and assign to param if param is null}
${parameter:?show this error if param is null}
They have more tweakable behaviours than those listed, and as I said, there are other ways to manipulate strings (a common one being $(command substitution)
combined with sed or any other external filter). But, they are so easily found by typing man bash
that I don't feel it merits to further extend this post.
Solution 4
In bash you can try this:
stringZ=abcABC123ABCabc
# 0123456789.....
# 0-based indexing.
echo ${stringZ:0:2} # prints ab
More samples in The Linux Documentation Project
Solution 5
${string:position:length}
Related videos on Youtube
Arman
Updated on March 01, 2020Comments
-
Arman about 4 years
You have a single asp.net webapi project with different areas.
The question is is it possible to host one of them over the Internet and make it accessible for web users while keeping the other(s) accessible only for the local network users?
I know it's not possible to assign areas different pools and nothing comes to mind on how to configure IIS to limit the users of any of the areas to the local network.
One possible solution is for sure just taking the local areas out of the main project and hosting them under dedicated app pools and IIS apps. And the second way to do this is to perform fine-grained security and simply restrict the access of the users based on the custom authentication attributes.
But I hope it should really be possible to deny access to the website based on some directory/path/pattern filtering. Any ideas guys?
-
Adrian W over 5 yearsNot really a duplicate. Extract substring in Bash asks for cutting out a sequence of characters surrounded by a certain delimiter. This question asks for cutting out a piece of a string giving numerical values for offset and length like
substr()
does. This is not the same.
-
-
Jason over 15 yearsinteresting, I did not know about this. For more flexibile substring options: man cut
-
Clinton Pierce over 15 yearsShell extensions are nice, but... meh.
-
dmckee --- ex-moderator kitten over 15 yearsI mostly agree. I usually write shell scripts in vanilla /bin/sh. But I find that I have to know some bashisms to read shell scripts...
-
Toybuilder over 12 yearsEven though I have the "accepted" answer, I would like to point out that if you want to do a lot of sub-string extraction, using the built-in substring expansion (see dmckee's answer) is the more efficient way to go. That said, cut is easier to remember and use.
-
user1731553 about 8 yearswhat do we need to do if we want to start from 3rd char till end of the string ie: "abcdef" we need cdef then echo "abcdef" | cut -c3?"
-
becko about 7 yearsIs there something like
${str:3:-3}
to extract a substring from char 3 to last char minus -3? -
dmckee --- ex-moderator kitten about 7 years@becko My current bash manpage (MacOS 10.12, so the BSD lineage, I think) has considerably more than the quote above including
If offset evaluates to a number less than zero, the value is used as an offset from the end of the value of parameter.
Meaning that you would want${str:-3:3}
. -
becko about 7 yearsIt doesn't work:
str="abcdefghijklmn"; echo ${str:-2:2}
returnsabcdefghijklmn
-
becko about 7 yearsOh, but
echo ${str:2:-2}
does what I want. -
dmckee --- ex-moderator kitten about 7 years@becko I think we're tripping up on "evaluates to". Neither of your examples work for me, but
str="abcdefghijklmn"; echo ${str:(-2):2}
returnsmn
. That kind of thing is why I gave up trying to understand what the heck the shell is doing. -
becko about 7 years@dmckee I'm on
zsh
. -
ArtOfWarfare over 6 years
cut
has some useful arguments you can use.-f
changes it from counting characters to counting fields, delimited by TAB by default or by any character you specify following-d
. So to get your input string up until but not including the first slash (exactly what I wanted), you can do:cut -d/ -f-1
, which can be read as "cut on substrings delimited by /, only return the first one". -
Dan Rosenstark over 5 yearsAs usual, sitting down here with no upvotes, WTF. This worked so well for me in my parse_git_branch command. Naice!
-
Charles Duffy over 5 yearsHeredocs work without bash (
<<EOF
, your contents, thenEOF
), and typically (on systems whereTMPDIR
in on tmpfs/shmfs/etc) cost less than the subshell to runecho
would. -
JepZ over 5 yearsJust remember, that 'indexed substring expansion' is not part of the POSIX standard. So while it is probably faster on bash than the alternatives, it might get in your way when you want to run your script on different operating systems.
-
ToiletGuy about 3 yearsIs there a syntax to replace the number 2 with infinity ?
-
ToiletGuy about 3 yearsCan the length become the infinity ?
-
hdrz almost 3 years@ToiletGuy Yes, just discard it.
echo ${stringZ:9}
prints ABCabc -
Manuel Jordan over 2 yearsConsider to indicate quickly: what does
-c
do? -
Manuel Jordan over 2 years@ArtOfWarfare huge thanks for your comment - it explains the following answer: stackoverflow.com/a/428118/3665178