Command substitution in sed

I want to read the first six characters of a text file in a line and add to it any other non-empty line in this file with this line. An example of such a file could be:

04/17 Walmart .toys $ 70 .cash $ -70

Caltex .gas 20 $ .cheque $ -20

McDonalds .burger 1 $ .cash $ -1

Each record, i.e.: each non-empty line, needs a date that, for reasons of simple data entry, was entered only in the first line. Entries are separated by 1 or more blank lines. The result will 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 non-empty strings with things like ^ [^ @] + [] *. [] ([^; {}:] +) [] * $ , but I don’t know how to implement this for non-empty strings.

This Bash script looks attractive to me, but I don’t know how to insert my line at the beginning then.

I also cannot find a direct answer to my question about Stack Overflow.

script, :

read -n 6 date < $1
sed 's/^/$(echo $date)/' | \
sed 's/^$(echo $date)\n//' | > $newName

(, : '04/17 ') , , .

, , sed :

sed: -e expression #1, char 10: unknown option to `s'
+4
4

sed:

read -rn 6 date < "$1"
sed -E 's#^([a-zA-Z]+)#'"$date"' \1#g' "$1" > newfile

.

: :

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" 

, $date, , . "" , , Perl sed, , , ...

( ):

04/17 Walmart .toys $ 70 .cash $ -70

04/17 Caltex .gas 20 $ .cheque $ -20

04/17 McDonalds .burger 1 $ .cash $ -1

. sed -r -E.

+5

Perl:

perl -plE 'if($.==1){$d=substr($_,0,6);next}elsif(/./){s/^/$d/}' file > new

04/17 Walmart .toys $ 70 .cash $ -70

04/17 Caltex .gas 20 $ .cheque $ -20

04/17 McDonalds .burger 1 $ .cash $ -1

file.bak

perl -i.bak -plE 'if($.==1){$d=substr($_,0,6);next}elsif(/./){s/^/$d/}' file

perl -i -plE 'if($.==1){$d=substr($_,0,6);next}elsif(/./){s/^/$d/}' file

, ,

perl -plE 'if($.==1){($d)=m|^(\d+/\d+\s)|;next}elsif(/./){s/^/$d/}' file

digit(s) / digit(s) space 1- .

l'L'l, , ( ), . . /./:

  • /\w/ - , , ;
  • /\S/ -

:

perl -plE '                    # Run the commands on every input line and print them.
    if( $. == 1) {             # If it is the 1st line
        $d = substr($_, 0, 6); # take the first 6 characters and store it to $d
        next                   # And continue to the next line.
    }
    elsif( /\S/ ) {            # Else if the line contains any nonspace character
        s/^/$d/                # add to the beginning the content of $d
    }
    ' file > new
+4

bash :

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

:

04/17 Walmart .toys $ 70 .cash $ -70

04/17 Caltex .gas 20 $ .cheque $ -20

04/17 McDonalds .burger 1 $ .cash $ -1
+3

sed, - :

"s#^#$(echo $date)#"

, :

"s#^#$date#"

Please note, however, that this approach is usually fragile (as you discovered), because you cannot treat a variable as a literal string.


Based on samples on an updated question, I would suggest using one awk command to process text. Something like this might give you sample output:

$ cat file
04/17 Walmart .toys $ 70 .cash $ -70

Caltex .gas 20 $ .cheque $ -20

McDonalds .burger 1 $ .cash $ -1

$ awk 'NR==1{d=$1}NR>1&&NF>0{$0=d" "$0}1' file
04/17 Walmart .toys $ 70 .cash $ -70

04/17 Caltex .gas 20 $ .cheque $ -20

04/17 McDonalds .burger 1 $ .cash $ -1
+2
source

Source: https://habr.com/ru/post/1676532/


All Articles