I want to read the first six characters of a text file into a string and prepend every other non-blank line in that file with that string. An example of such file could be:
04/17 Walmart .toys $ 70 .cash $ -70
Caltex .gas 20 $ .cheque $ -20
McDonalds .burger 1 $ .cash $ -1
Each entry, i.e.: each non-empty line, needs a date, which for reasons of easy data entry has been entered on the first line only. Entries are separated by 1 or more empty lines. The output would look like this:
04/17 Walmart .toys $ 70 .cash $ -70
04/17 Caltex .gas 20 $ .cheque $ -20
04/17 McDonalds .burger 1 $ .cash $ -1
I can match the non empty strings with things like ^[^@]+[ ]*.[ ]([^;{}:]+)[ ]*$, but I don't know how to actually implement that for non blank lines.
This Bash script looks attractive to me, but I don't know how then to insert my string at the start.
I also can't find the straight answer to my question on Stack Overflow.
I tried a script which accepts a file name:
read -n 6 date < $1
sed 's/^/$(echo $date)/' | \
sed 's/^$(echo $date)\n//' | > $newName
I was able to come up with prepending the date with space (e.g. the string: '04/17 ') to every line, and then remove the same from every line in which nothing follows.
However, it seems that sed doesn't accept the command substitution:
sed: -e expression #1, char 10: unknown option to `s'
You should be able to do this with one sed
command:
read -rn 6 date < "$1"
sed -E 's#^([a-zA-Z]+)#'"$date"' \1#g' "$1" > newfile
The capture group ensures there's at least one character on the line before inserting the date.
EDIT: Based on the revision to your question:
newfile="output.txt"
lineone=$(head -1 "$1");
read -rn 6 date <<< "$lineone"
sed -E 's#^([a-zA-Z]+)#'"$date"' \1#g; 1s#^.*$#'"$lineone"'#' "$1" > "$newfile"
Since you aren't doing an in-place edit, you can do the $date insertions, and then go back and swap out the first line since it would end up with two dates. There might be "better" ways to do this such as using Perl
, or losing the second sed
command, although this should at least give you a basic idea though on how it works...
Result (newfile):
04/17 Walmart .toys $ 70 .cash $ -70
04/17 Caltex .gas 20 $ .cheque $ -20
04/17 McDonalds .burger 1 $ .cash $ -1
NOTE: In some versions of
sed
the option for extended regex can either be-r
or-E
.
Pure bash
answer:
unset n
while read -r x ; do
case "${#n}$x" in 6) ;; 6*) x="$n$x" ;; *) n="${x:0:6}" ;; esac
echo "$x"
done < file > newfile
Output:
04/17 Walmart .toys $ 70 .cash $ -70
04/17 Caltex .gas 20 $ .cheque $ -20
04/17 McDonalds .burger 1 $ .cash $ -1
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With