Regex, delete all characters after the last occurrence of “/”
up vote
1
down vote
favorite
I have a list of pathnames like this in a file:
/path/to/directory/one.txt
/longer/path/to/some/directory/two.py
/path/with spaces/in/it/three.sh
I want to delete all characters after the last occurrence of "/",
so the desired output for the above is:
/path/to/directory/
/longer/path/to/some/directory/
/path/with spaces/in/it/
linux ubuntu text-processing command-line regular-expression
New contributor
add a comment |
up vote
1
down vote
favorite
I have a list of pathnames like this in a file:
/path/to/directory/one.txt
/longer/path/to/some/directory/two.py
/path/with spaces/in/it/three.sh
I want to delete all characters after the last occurrence of "/",
so the desired output for the above is:
/path/to/directory/
/longer/path/to/some/directory/
/path/with spaces/in/it/
linux ubuntu text-processing command-line regular-expression
New contributor
add a comment |
up vote
1
down vote
favorite
up vote
1
down vote
favorite
I have a list of pathnames like this in a file:
/path/to/directory/one.txt
/longer/path/to/some/directory/two.py
/path/with spaces/in/it/three.sh
I want to delete all characters after the last occurrence of "/",
so the desired output for the above is:
/path/to/directory/
/longer/path/to/some/directory/
/path/with spaces/in/it/
linux ubuntu text-processing command-line regular-expression
New contributor
I have a list of pathnames like this in a file:
/path/to/directory/one.txt
/longer/path/to/some/directory/two.py
/path/with spaces/in/it/three.sh
I want to delete all characters after the last occurrence of "/",
so the desired output for the above is:
/path/to/directory/
/longer/path/to/some/directory/
/path/with spaces/in/it/
linux ubuntu text-processing command-line regular-expression
linux ubuntu text-processing command-line regular-expression
New contributor
New contributor
edited Nov 18 at 18:17
Scott
6,59942650
6,59942650
New contributor
asked Nov 18 at 6:31
user321546
82
82
New contributor
New contributor
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
up vote
0
down vote
accepted
sed 's![^/]*$!!'
This does the following:
- Use a delimiter other than
/
,
because the regular expression contains/
.
(I like!
and|
because they look like dividing lines;
other people use@
,#
,^
, or whatever they feel like.
It is possible to use/
in a regular expression delimited by/
,
but that can be hard for a person to read.) - Find a string of (zero or more) characters other than
/
.
(Make it as long as possible.)
But it must be at the end of the line. - And replace it with nothing.
Caveat: an input line that contains no /
characters
will be totally wiped out
(i.e., the entire contents of the line will be deleted,
leaving only a blank line).
If we wanted to fix that,
and let a line with no slashes pass through unchanged,
we could change the command to
sed 's!/[^/]*$!/!'
This is the same as the first answer,
except it matches the last /
and all the characters after it,
and then replaces them with a /
(in effect, leaving the final /
in the input line alone).
So, where the first answer finds one.txt
and replaces it with nothing,
this finds /one.txt
and replaces it with /
.
But, on a line that contains no /
characters,
the first answer matches the entire line and replaces it with nothing,
while this one would not find a match,
and so would not make a substitution.
We could use /
as the delimiter in this command,
but then it would have to be
sed 's//[^/]*$///'
“escaping” the slashes that are part of the regular expression
and the replacement string
by preceding them with backslashes ().
Some people find this jungle of “leaning trees”
to be harder to read and maintain,
but it basically comes down to a matter of style.
The/
in the regular expression occurs within a character class, where all characters are literal, so changing the delimiter is not strictly needed.
– Kusalananda
Nov 18 at 18:14
add a comment |
up vote
0
down vote
You may use the dirname
utility:
xargs -I {} dirname {} <file.txt
This would give you the pathnames of each parent directory in the list. For the given list, it would produce
/path/to/directory
/longer/path/to/some/directory
/path/with spaces/in/it
To embed a newline in a path, use
/some/path with a
newline/in/it
And to embed quotes, escape them as e.g. "
.
(1) The question says "delete all characters after the last occurrence of/
", and shows example output that retains the last/
. This answer does that only if the first character on an input line is the only/
on the line. (2) This solution will fail if any line contains quote(s) ('
or"
).
– Scott
Nov 18 at 18:28
@Scott (1) Sure, the only difference between the directory pathname with and without the trailing/
is that without the trailing/
I might refer to a symbolic link directory entry. while with/
you would refer to the.
entry within the directory (symbolic links resolved). In either case, it does not make much difference when it comes to actually using the pathname.
– Kusalananda
Nov 18 at 18:38
@Scott (2) Yes, it is required that literal quotes are escaped in the data. This is a requirement byxargs
and mentioned in the standard.
– Kusalananda
Nov 18 at 18:42
Of course I know that. My point was that the question didn't say whether there were quotes (a.k.a. apostrophes) in the input, or whether they were escaped, and the answer didn't disclose the constraint. P.S. Of course, this also requires that backslashes be escaped. P.P.S. Also, this answer turns lines with no/
into.
, which is no better than clobbering them.
– Scott
Nov 18 at 18:53
@Scott It depends on what you want to use the result for. A dot is the correct directory to find a file whose path is specified with no path component. You cancd
to.
, butcd ''
may take you elsewhere.
– Kusalananda
Nov 18 at 18:56
add a comment |
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
0
down vote
accepted
sed 's![^/]*$!!'
This does the following:
- Use a delimiter other than
/
,
because the regular expression contains/
.
(I like!
and|
because they look like dividing lines;
other people use@
,#
,^
, or whatever they feel like.
It is possible to use/
in a regular expression delimited by/
,
but that can be hard for a person to read.) - Find a string of (zero or more) characters other than
/
.
(Make it as long as possible.)
But it must be at the end of the line. - And replace it with nothing.
Caveat: an input line that contains no /
characters
will be totally wiped out
(i.e., the entire contents of the line will be deleted,
leaving only a blank line).
If we wanted to fix that,
and let a line with no slashes pass through unchanged,
we could change the command to
sed 's!/[^/]*$!/!'
This is the same as the first answer,
except it matches the last /
and all the characters after it,
and then replaces them with a /
(in effect, leaving the final /
in the input line alone).
So, where the first answer finds one.txt
and replaces it with nothing,
this finds /one.txt
and replaces it with /
.
But, on a line that contains no /
characters,
the first answer matches the entire line and replaces it with nothing,
while this one would not find a match,
and so would not make a substitution.
We could use /
as the delimiter in this command,
but then it would have to be
sed 's//[^/]*$///'
“escaping” the slashes that are part of the regular expression
and the replacement string
by preceding them with backslashes ().
Some people find this jungle of “leaning trees”
to be harder to read and maintain,
but it basically comes down to a matter of style.
The/
in the regular expression occurs within a character class, where all characters are literal, so changing the delimiter is not strictly needed.
– Kusalananda
Nov 18 at 18:14
add a comment |
up vote
0
down vote
accepted
sed 's![^/]*$!!'
This does the following:
- Use a delimiter other than
/
,
because the regular expression contains/
.
(I like!
and|
because they look like dividing lines;
other people use@
,#
,^
, or whatever they feel like.
It is possible to use/
in a regular expression delimited by/
,
but that can be hard for a person to read.) - Find a string of (zero or more) characters other than
/
.
(Make it as long as possible.)
But it must be at the end of the line. - And replace it with nothing.
Caveat: an input line that contains no /
characters
will be totally wiped out
(i.e., the entire contents of the line will be deleted,
leaving only a blank line).
If we wanted to fix that,
and let a line with no slashes pass through unchanged,
we could change the command to
sed 's!/[^/]*$!/!'
This is the same as the first answer,
except it matches the last /
and all the characters after it,
and then replaces them with a /
(in effect, leaving the final /
in the input line alone).
So, where the first answer finds one.txt
and replaces it with nothing,
this finds /one.txt
and replaces it with /
.
But, on a line that contains no /
characters,
the first answer matches the entire line and replaces it with nothing,
while this one would not find a match,
and so would not make a substitution.
We could use /
as the delimiter in this command,
but then it would have to be
sed 's//[^/]*$///'
“escaping” the slashes that are part of the regular expression
and the replacement string
by preceding them with backslashes ().
Some people find this jungle of “leaning trees”
to be harder to read and maintain,
but it basically comes down to a matter of style.
The/
in the regular expression occurs within a character class, where all characters are literal, so changing the delimiter is not strictly needed.
– Kusalananda
Nov 18 at 18:14
add a comment |
up vote
0
down vote
accepted
up vote
0
down vote
accepted
sed 's![^/]*$!!'
This does the following:
- Use a delimiter other than
/
,
because the regular expression contains/
.
(I like!
and|
because they look like dividing lines;
other people use@
,#
,^
, or whatever they feel like.
It is possible to use/
in a regular expression delimited by/
,
but that can be hard for a person to read.) - Find a string of (zero or more) characters other than
/
.
(Make it as long as possible.)
But it must be at the end of the line. - And replace it with nothing.
Caveat: an input line that contains no /
characters
will be totally wiped out
(i.e., the entire contents of the line will be deleted,
leaving only a blank line).
If we wanted to fix that,
and let a line with no slashes pass through unchanged,
we could change the command to
sed 's!/[^/]*$!/!'
This is the same as the first answer,
except it matches the last /
and all the characters after it,
and then replaces them with a /
(in effect, leaving the final /
in the input line alone).
So, where the first answer finds one.txt
and replaces it with nothing,
this finds /one.txt
and replaces it with /
.
But, on a line that contains no /
characters,
the first answer matches the entire line and replaces it with nothing,
while this one would not find a match,
and so would not make a substitution.
We could use /
as the delimiter in this command,
but then it would have to be
sed 's//[^/]*$///'
“escaping” the slashes that are part of the regular expression
and the replacement string
by preceding them with backslashes ().
Some people find this jungle of “leaning trees”
to be harder to read and maintain,
but it basically comes down to a matter of style.
sed 's![^/]*$!!'
This does the following:
- Use a delimiter other than
/
,
because the regular expression contains/
.
(I like!
and|
because they look like dividing lines;
other people use@
,#
,^
, or whatever they feel like.
It is possible to use/
in a regular expression delimited by/
,
but that can be hard for a person to read.) - Find a string of (zero or more) characters other than
/
.
(Make it as long as possible.)
But it must be at the end of the line. - And replace it with nothing.
Caveat: an input line that contains no /
characters
will be totally wiped out
(i.e., the entire contents of the line will be deleted,
leaving only a blank line).
If we wanted to fix that,
and let a line with no slashes pass through unchanged,
we could change the command to
sed 's!/[^/]*$!/!'
This is the same as the first answer,
except it matches the last /
and all the characters after it,
and then replaces them with a /
(in effect, leaving the final /
in the input line alone).
So, where the first answer finds one.txt
and replaces it with nothing,
this finds /one.txt
and replaces it with /
.
But, on a line that contains no /
characters,
the first answer matches the entire line and replaces it with nothing,
while this one would not find a match,
and so would not make a substitution.
We could use /
as the delimiter in this command,
but then it would have to be
sed 's//[^/]*$///'
“escaping” the slashes that are part of the regular expression
and the replacement string
by preceding them with backslashes ().
Some people find this jungle of “leaning trees”
to be harder to read and maintain,
but it basically comes down to a matter of style.
edited Nov 18 at 18:53
answered Nov 18 at 6:43
Scott
6,59942650
6,59942650
The/
in the regular expression occurs within a character class, where all characters are literal, so changing the delimiter is not strictly needed.
– Kusalananda
Nov 18 at 18:14
add a comment |
The/
in the regular expression occurs within a character class, where all characters are literal, so changing the delimiter is not strictly needed.
– Kusalananda
Nov 18 at 18:14
The
/
in the regular expression occurs within a character class, where all characters are literal, so changing the delimiter is not strictly needed.– Kusalananda
Nov 18 at 18:14
The
/
in the regular expression occurs within a character class, where all characters are literal, so changing the delimiter is not strictly needed.– Kusalananda
Nov 18 at 18:14
add a comment |
up vote
0
down vote
You may use the dirname
utility:
xargs -I {} dirname {} <file.txt
This would give you the pathnames of each parent directory in the list. For the given list, it would produce
/path/to/directory
/longer/path/to/some/directory
/path/with spaces/in/it
To embed a newline in a path, use
/some/path with a
newline/in/it
And to embed quotes, escape them as e.g. "
.
(1) The question says "delete all characters after the last occurrence of/
", and shows example output that retains the last/
. This answer does that only if the first character on an input line is the only/
on the line. (2) This solution will fail if any line contains quote(s) ('
or"
).
– Scott
Nov 18 at 18:28
@Scott (1) Sure, the only difference between the directory pathname with and without the trailing/
is that without the trailing/
I might refer to a symbolic link directory entry. while with/
you would refer to the.
entry within the directory (symbolic links resolved). In either case, it does not make much difference when it comes to actually using the pathname.
– Kusalananda
Nov 18 at 18:38
@Scott (2) Yes, it is required that literal quotes are escaped in the data. This is a requirement byxargs
and mentioned in the standard.
– Kusalananda
Nov 18 at 18:42
Of course I know that. My point was that the question didn't say whether there were quotes (a.k.a. apostrophes) in the input, or whether they were escaped, and the answer didn't disclose the constraint. P.S. Of course, this also requires that backslashes be escaped. P.P.S. Also, this answer turns lines with no/
into.
, which is no better than clobbering them.
– Scott
Nov 18 at 18:53
@Scott It depends on what you want to use the result for. A dot is the correct directory to find a file whose path is specified with no path component. You cancd
to.
, butcd ''
may take you elsewhere.
– Kusalananda
Nov 18 at 18:56
add a comment |
up vote
0
down vote
You may use the dirname
utility:
xargs -I {} dirname {} <file.txt
This would give you the pathnames of each parent directory in the list. For the given list, it would produce
/path/to/directory
/longer/path/to/some/directory
/path/with spaces/in/it
To embed a newline in a path, use
/some/path with a
newline/in/it
And to embed quotes, escape them as e.g. "
.
(1) The question says "delete all characters after the last occurrence of/
", and shows example output that retains the last/
. This answer does that only if the first character on an input line is the only/
on the line. (2) This solution will fail if any line contains quote(s) ('
or"
).
– Scott
Nov 18 at 18:28
@Scott (1) Sure, the only difference between the directory pathname with and without the trailing/
is that without the trailing/
I might refer to a symbolic link directory entry. while with/
you would refer to the.
entry within the directory (symbolic links resolved). In either case, it does not make much difference when it comes to actually using the pathname.
– Kusalananda
Nov 18 at 18:38
@Scott (2) Yes, it is required that literal quotes are escaped in the data. This is a requirement byxargs
and mentioned in the standard.
– Kusalananda
Nov 18 at 18:42
Of course I know that. My point was that the question didn't say whether there were quotes (a.k.a. apostrophes) in the input, or whether they were escaped, and the answer didn't disclose the constraint. P.S. Of course, this also requires that backslashes be escaped. P.P.S. Also, this answer turns lines with no/
into.
, which is no better than clobbering them.
– Scott
Nov 18 at 18:53
@Scott It depends on what you want to use the result for. A dot is the correct directory to find a file whose path is specified with no path component. You cancd
to.
, butcd ''
may take you elsewhere.
– Kusalananda
Nov 18 at 18:56
add a comment |
up vote
0
down vote
up vote
0
down vote
You may use the dirname
utility:
xargs -I {} dirname {} <file.txt
This would give you the pathnames of each parent directory in the list. For the given list, it would produce
/path/to/directory
/longer/path/to/some/directory
/path/with spaces/in/it
To embed a newline in a path, use
/some/path with a
newline/in/it
And to embed quotes, escape them as e.g. "
.
You may use the dirname
utility:
xargs -I {} dirname {} <file.txt
This would give you the pathnames of each parent directory in the list. For the given list, it would produce
/path/to/directory
/longer/path/to/some/directory
/path/with spaces/in/it
To embed a newline in a path, use
/some/path with a
newline/in/it
And to embed quotes, escape them as e.g. "
.
edited Nov 18 at 18:49
answered Nov 18 at 18:12
Kusalananda
116k15218352
116k15218352
(1) The question says "delete all characters after the last occurrence of/
", and shows example output that retains the last/
. This answer does that only if the first character on an input line is the only/
on the line. (2) This solution will fail if any line contains quote(s) ('
or"
).
– Scott
Nov 18 at 18:28
@Scott (1) Sure, the only difference between the directory pathname with and without the trailing/
is that without the trailing/
I might refer to a symbolic link directory entry. while with/
you would refer to the.
entry within the directory (symbolic links resolved). In either case, it does not make much difference when it comes to actually using the pathname.
– Kusalananda
Nov 18 at 18:38
@Scott (2) Yes, it is required that literal quotes are escaped in the data. This is a requirement byxargs
and mentioned in the standard.
– Kusalananda
Nov 18 at 18:42
Of course I know that. My point was that the question didn't say whether there were quotes (a.k.a. apostrophes) in the input, or whether they were escaped, and the answer didn't disclose the constraint. P.S. Of course, this also requires that backslashes be escaped. P.P.S. Also, this answer turns lines with no/
into.
, which is no better than clobbering them.
– Scott
Nov 18 at 18:53
@Scott It depends on what you want to use the result for. A dot is the correct directory to find a file whose path is specified with no path component. You cancd
to.
, butcd ''
may take you elsewhere.
– Kusalananda
Nov 18 at 18:56
add a comment |
(1) The question says "delete all characters after the last occurrence of/
", and shows example output that retains the last/
. This answer does that only if the first character on an input line is the only/
on the line. (2) This solution will fail if any line contains quote(s) ('
or"
).
– Scott
Nov 18 at 18:28
@Scott (1) Sure, the only difference between the directory pathname with and without the trailing/
is that without the trailing/
I might refer to a symbolic link directory entry. while with/
you would refer to the.
entry within the directory (symbolic links resolved). In either case, it does not make much difference when it comes to actually using the pathname.
– Kusalananda
Nov 18 at 18:38
@Scott (2) Yes, it is required that literal quotes are escaped in the data. This is a requirement byxargs
and mentioned in the standard.
– Kusalananda
Nov 18 at 18:42
Of course I know that. My point was that the question didn't say whether there were quotes (a.k.a. apostrophes) in the input, or whether they were escaped, and the answer didn't disclose the constraint. P.S. Of course, this also requires that backslashes be escaped. P.P.S. Also, this answer turns lines with no/
into.
, which is no better than clobbering them.
– Scott
Nov 18 at 18:53
@Scott It depends on what you want to use the result for. A dot is the correct directory to find a file whose path is specified with no path component. You cancd
to.
, butcd ''
may take you elsewhere.
– Kusalananda
Nov 18 at 18:56
(1) The question says "delete all characters after the last occurrence of
/
", and shows example output that retains the last /
. This answer does that only if the first character on an input line is the only /
on the line. (2) This solution will fail if any line contains quote(s) ('
or "
).– Scott
Nov 18 at 18:28
(1) The question says "delete all characters after the last occurrence of
/
", and shows example output that retains the last /
. This answer does that only if the first character on an input line is the only /
on the line. (2) This solution will fail if any line contains quote(s) ('
or "
).– Scott
Nov 18 at 18:28
@Scott (1) Sure, the only difference between the directory pathname with and without the trailing
/
is that without the trailing /
I might refer to a symbolic link directory entry. while with /
you would refer to the .
entry within the directory (symbolic links resolved). In either case, it does not make much difference when it comes to actually using the pathname.– Kusalananda
Nov 18 at 18:38
@Scott (1) Sure, the only difference between the directory pathname with and without the trailing
/
is that without the trailing /
I might refer to a symbolic link directory entry. while with /
you would refer to the .
entry within the directory (symbolic links resolved). In either case, it does not make much difference when it comes to actually using the pathname.– Kusalananda
Nov 18 at 18:38
@Scott (2) Yes, it is required that literal quotes are escaped in the data. This is a requirement by
xargs
and mentioned in the standard.– Kusalananda
Nov 18 at 18:42
@Scott (2) Yes, it is required that literal quotes are escaped in the data. This is a requirement by
xargs
and mentioned in the standard.– Kusalananda
Nov 18 at 18:42
Of course I know that. My point was that the question didn't say whether there were quotes (a.k.a. apostrophes) in the input, or whether they were escaped, and the answer didn't disclose the constraint. P.S. Of course, this also requires that backslashes be escaped. P.P.S. Also, this answer turns lines with no
/
into .
, which is no better than clobbering them.– Scott
Nov 18 at 18:53
Of course I know that. My point was that the question didn't say whether there were quotes (a.k.a. apostrophes) in the input, or whether they were escaped, and the answer didn't disclose the constraint. P.S. Of course, this also requires that backslashes be escaped. P.P.S. Also, this answer turns lines with no
/
into .
, which is no better than clobbering them.– Scott
Nov 18 at 18:53
@Scott It depends on what you want to use the result for. A dot is the correct directory to find a file whose path is specified with no path component. You can
cd
to .
, but cd ''
may take you elsewhere.– Kusalananda
Nov 18 at 18:56
@Scott It depends on what you want to use the result for. A dot is the correct directory to find a file whose path is specified with no path component. You can
cd
to .
, but cd ''
may take you elsewhere.– Kusalananda
Nov 18 at 18:56
add a comment |
user321546 is a new contributor. Be nice, and check out our Code of Conduct.
user321546 is a new contributor. Be nice, and check out our Code of Conduct.
user321546 is a new contributor. Be nice, and check out our Code of Conduct.
user321546 is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f482477%2fregex-delete-all-characters-after-the-last-occurrence-of%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown