sed - get only text without extension

Viewed 147

How do I remove the extension in this SED statement?

Through

sed 's/.* - //'

File content

2021-04-21_@fluffyban_6953588770591509765.mp4 - Filename.mp4

Actual

Filename.mp4

Desired

Filename
6 Answers

With your shown samples only. This could be done with simple codes in awk,sed and perl as follows.

1st solution: Using sed, perform simple substitutions and you will get desired output.

sed 's/.*- //;s/\.mp4$//' Input_file

2nd solution: Using awk its more simpler, creating different field separator and just print appropriate 2nd last column.

awk -F'- |.mp4' '{print $(NF-1)}' Input_file

3rd solution: Using substitution method in awk to get the required value as per OP's requirement.

awk '{gsub(/.*- |\.mp4$/,"")} 1' Input_file

4th solution: With perl one liner we could grab the appropriate needed value by setting field separators as dash spaces and .mp4 as follows:

perl -a -F'-\s+|\.mp4'  -ne 'print "$F[$#F-1]\n";' Input_file

The Bash way (which works in most similar shells such us zsh,sh,ksh) is:

fn="2021-04-21_@fluffyban_6953588770591509765.mp4 - Filename.mp4"

base=${fn%.*}
ext=${fn#$base.}

echo "$base"
echo "$ext"

Prints:

2021-04-21_@fluffyban_6953588770591509765.mp4 - Filename
mp4

You can use

#!/bin/bash
s='2021-04-21_@fluffyban_6953588770591509765.mp4 - Filename.mp4'
sed -n 's/.* - \([^.]*\).*/\1/p' <<< "$s"
# => Filename

See the online demo.

Details:

  • -n - suppress default line output
  • s/ - substitute found pattern
  • .* - \([^.]*\).* - any text, space, -, space, then any zero or more chars other than a dot captured into Group 1, and then any text
  • /\1/ - replace found matches with Group 1 value
  • p - print the result of the substitution.

Using gnu awk you can also use a capture group to get the filename

match($0, /.* - ([^.]+)\.mp4$/, a) {print a[1]}' file

Regex explanation

  • .* - Match the last occurrence of -
  • ( Capture group 1 (Referred to by a[1] in the awk example)
    • [^.]+ Match 1+ times any char except a dot
  • ) Close group 1
  • \.mp4$ Match .mp4 at the end of the string

Awk explanation

awk '
match($0, /.* - ([^.]+)\.mp4$/, a) {  # Test if the line using $0 matches the pattern
  print a[1]                          # Print the value of group 1
}
' file

Yet another awk:

awk '{sub(/\.[^.]+$/, ""); print $NF}' file

Filename
gawk/mawk/mawk2 'BEGIN { FS = "( \- |[.][^. ]+$)"

    } NF > 2 { print $(NF-1) }'

no substr(), index(), match(), or sub() needed. If you're VERY certain " - " can only occur once, then

awk 'BEGIN { FS = "(^.* \- |[.][^. ]+$)"; OFS = "" } —-NF'
Related