0

I have a bash script that renames certain text files according to their content. A file with the following content e.g. should be renamed to 2020-05-11_Chess-com.txt.

[Site "Chess.com"]
[Date "2020-05-11"]
[White "Computer 6"]
[Result "0-1"]
[Termination " won by checkmate"]
... More content ...

Below you find a mockup of the script I am currently using:

#!/bin/bash 
site=$(sed -n '1p' < "$1" | cut -d ' ' -f2 | tr -d '"]' | tr ' .' '-')
datum=$(sed -n '2s/[^0-9-]*\([0-9-]*\)[^0-9-]*/\1/p' < "$1")

echo "${datum}_${site}"  # 2020-05-11_Chess-com
echo "${datum}_${site}".txt  # .txt-05-11_Chess-com
echo "$datum"_"${site}".txt  # .txt-05-11_Chess-com

The result of the string substitution in the last two lines is totally unexpected for me and I find it difficult to find any explanation for the script's odd behavior.

One observation I made however, although I did not help much, was that if I substitute the line site=$(...) with site="Chess-com", then I get the expected result 2020-05-11_Chess-com.txt.

Thomas
  • 292
  • 2
  • 6

2 Answers2

2

Your script is working fine with the examples you provided, but it requires the input to be completely regular. Perhaps switch to something which actually checks that the file is in the expected format.

#!/bin/sh
awk '/\[Site / { site=$1; gsub(/[]"\r]/, "", site) }
    /\[Date / { datum=$2; gsub(/[]"\r]/, "", datum) }
    END { print datum "_" site ".txt" }' "$1"

This also takes care of removing any DOS carriage returns, which I guess is probably the source of your problem.

tripleee
  • 175,061
  • 34
  • 275
  • 318
  • Why would you not just prep the file using dos2unix instead? – bob dylan Aug 13 '20 at 08:29
  • No objection to that, but this is IMHO a better script too. – tripleee Aug 13 '20 at 08:29
  • Thanks for the explanation and the link to the duplicated question. However I have to admit, that I would never have found it myself. Bythe way, I knew there wold be someone suggesting a totally awk-based solution ;-) – Thomas Aug 16 '20 at 16:15
1

Your code looks fine but i'd suggest some improvements

site=$(sed -n 's/\[Site "\(.*\)"\]/\1/p' "$1")
date=$(sed -n 's/\[Date "\(.*\)"\]/\1/p' "$1")
echo "${date}_$site.txt"

Or like this

read -d\n site date trash <<< $(sed 's|^.*"\(.*\)".*$|\1|g' "$1")
printf '%s_%s.txt' $date $site

Or like this

sed -n 'N;s|.*Site.*"\(.*\)".*"\(.*\)".*|\2_\1.txt|p' "$1"
Ivan
  • 6,188
  • 1
  • 16
  • 23
  • Thanks for all the alternative solutions to my script. This is really helpful for improving my bash-scripting skills. – Thomas Aug 16 '20 at 16:16