Search code examples
regexbashsedmatchswap

Swap two words with regex in a text file using bash


I have file adr.txt with info:

Franklin Avenue, US, 33123
Laurel Drive, US, 59121
Street King, UK, 00939
Street Williams, US, 19123
Warren Avenue, UK, 93891
Street Court, UK, 89730
Country Club Road, US, 10865 
Madison Avenue, US, 36975
Street Front, US, 41911
Cedar Lane, UK, 21563
Garfield Avenue, UK, 00842
Street Cottage, US, 33205
Arlington Avenue, US, 94008
Cedar Avenue, US, 72635
Windsor Drive, US, 34384
Devon Court, UK, 13789
Garfield Avenue, US, 86115
Street Olive, US, 63007
Street Williams, US, 54675
Franklin Avenue, US, 82479

I need to swap the words "Street" and the name of the street to get the following - the name should come first, and then the word "Street".

Franklin Avenue, US, 33123
Laurel Drive, US, 59121
King Street, UK, 00939
Williams Street, US, 19123
Warren Avenue, UK, 93891
Court Street, UK, 89730
Country Club Road, US, 10865 
Madison Avenue, US, 36975
Front Street, US, 41911
Cedar Lane, UK, 21563
Garfield Avenue, UK, 00842
Cottage Street, US, 33205
Arlington Avenue, US, 94008
Cedar Avenue, US, 72635
Windsor Drive, US, 34384
Devon Court, UK, 13789
Garfield Avenue, US, 86115
Olive Street, US, 63007
Williams Street, US, 54675
Franklin Avenue, US, 82479

As an example, "sed" command works for me sed -i 's/\(Street\) \(King\)/\2 \1/' adr.txt What regular expression can be used to automatically catch all words with a street name? I tried sed -i 's/\(Street\) \([WO]{1}[a-z]*[es]{1}\,\)/\2 \1/' adr.txt I checked the regular expression [WO]{1}[a-z]*[se]{1}\, on regex101.com. It looks for the names "Williams," "Olive," But it does not work in "sed" command.


Solution

  • Your regex attempt was very weird. The simple sed solution would be

    sed -i 's/^\(Street\) \([^ ,]*\)/\2 \1/' adr.txt
    

    Though perhaps better to use Awk for this.

    awk '/^Street [^ ,]+,/ {
        two=$2; $2=$1 ",";
        sub(/,$/, "", two);
        $1=two }1' adr.txt >newfile
    mv newfile adr.txt
    

    As an aside, https://regex101.com/ supports a number of regex dialects, but none of them is exactly the one understood by sed.

    Also, {1} in a regex is never useful; if you want to repeat something once, the expression before {1} already does exactly that.