Question

I'm working on a project where I'm formating over 500 readme files. Each file contains the following (including the whitespace) and I'd like to make a bash script for the task. I successfully used bash to create all the readme files from data, but I'm having trouble trying to find a way use sed, grep, and regexs to make this work.

WHAT THE FILE LOOKS LIKE NOW:

"1.0.0": "text1"
  "1.1.15": "text2"
  "2.1.2": "text3"
  "4.55.3a": "text4"

WHAT I WANT IT TO LOOK LIKE:

**v4.55.3a**
 - text 4

**v2.1.2**
 - text 3

**v1.1.15**
 - text 2

**v1.0.0**
 - text 1

BASH SCRIPT (this will format the strings in the files):

f=$(find . -type f -name README.md)
for item in $f; do
  #format version
  #format string
done

So pretty much I'm looking for some help on building a script that'll format the contents. Thanks everyone for your input.

UPDATES
Are all lines but the 1st in the input files really indented?
- Some are, some aren't.
Do you really want the version numbers enclosed in ** in the output?
- Yes, its for the github markup.
Looks like you want the output files sorted by version number in descending order, correct?
- Correct!

Was it helpful?

Solution

With the input and output formatted exactly as currently specified in the question:

tac "$item" | awk -F\" '{ printf "**v%s**\n - %s\n", $2, $4 }' > "/tmp/$item" &&
  mv "/tmp/$item" "$item"

Note:

  • This assumes that simply reversing the input order is sufficient to get the desired output sorting [since confirmed by the OP] - if true sorting is needed, it gets trickier
    (sort -t. -r -b -n -k1.2,1 -k2,2 -k3,3 "$item").
  • On OSX, use tail -r instead of tac.

Also, it's better not to parse command output with for ... in, as that would break with paths with embedded spaces, for instance.

A more robust solution is to read into an array:

IFS=$'\n' read -r -d '' -a files <<<"$(find . -type f -name README.md)"
for item in "${files[@]}"; do
   # ...
done
  • The only caveat is that paths mustn't contain embedded newlines, but that's typically not a concern.
  • If you're using bash 4+, you can use readarray -t files <<<"$(find . -type f -name README.md)" instead.

Alternatively, process find's output directly in a loop:

find . -type f -name README.md -print0 | while IFS= read -r -d '' item; do ...

OTHER TIPS

My guess is that you my like some like this:

sort -r -k1 file | awk -F\" '{print "**v"$2"**\n -"$4"\n"}'
**v4.55.3a**
 -text4

**v2.1.2**
 -text3

**v1.1.15**
 -text2

**v1.0.0**
 -text1

It revers sort the data based on version number, then print it out in groups.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top