Home > database >  Rename file containing '-' character with sed
Rename file containing '-' character with sed

Time:10-23

A series of file names should be in format:

ABCDEF - XY1234 - FileName.ext

(The middle section is fixed length (2 alpha 4 numeric), the first and last sections can be longer or shorter than the example. The extension will always be three alphanumeric characters.)

However, some files do not have the hyphens surrounded by spaces:

EFGHI- WX2345 -FileName.ext
JKLMN-VW3456 - FileName.ext
OPQRS - UV4567- FileName.ext

Is there a way to replace all these combinations "X -X", "X-X", and "X- X" with "X - X" using sed?

(I have tried the pattern of a non-whitespace character followed by a hyphen - '\S\-' as my pattern, but replacing this with a space followed by the hyphen '\ \-' then means I lose the character represented by the '\S'. Had this worked my intention would have been to pass each filename through the three variations to ensure compliance.)

CodePudding user response:

Is there a way to replace all these combinations "X -X", "X-X", and "X- X" with "X - X" using sed?

You may use this sed:

sed -E 's/[[:blank:]]*-[[:blank:]]*/ - /g' file

EFGHI - WX2345 - FileName.ext
JKLMN - VW3456 - FileName.ext
OPQRS - UV4567 - FileName.ext

Breakdown:

  • [[:blank:]]*-[[:blank:]]*: matches - surrounded by 0 or whitespaces on both sides
  • -: replaced that with - surrounded by a single space on both sides

An awk solution would be:

awk -F '[[:blank:]]*-[[:blank:]]*' -v OFS=' - ' '{$1=$1} 1' file

EFGHI - WX2345 - FileName.ext
JKLMN - VW3456 - FileName.ext
OPQRS - UV4567 - FileName.ext

or even this:

awk '{gsub(/[[:blank:]]*-[[:blank:]]*/, " - ")} 1' file

CodePudding user response:

Assumptions:

  • white space only shows up before/after the hyphens
  • there are only 2 hyphens in a filename
  • all filenames contain 2 hyphens

One bash idea using parameter substitutions to determine new filenames:

while read -r fname
do
    newfname="${fname// /}"             # remove all spaces
    newfname="${newfname//-/ - }"       # add leading/trailing space to all hyphens
    # do something with (old) $fname and $newfname
done < <(printf "%s\n" 'EFGHI- WX2345 -FileName.ext' 'JKLMN-VW3456 - FileName.ext' 'OPQRS - UV4567- FileName.ext')

NOTES:

  • printf only used here to simulate feeding list of filenames to the while loop
  • OP would replace the printf with whatever command generates the list of filenames (eg, find, cat list_of_filenames.txt, etc)
  • Related