Locke (3-3) gave up three runs in the first two innings, and then shut out the Marlins over his last five. The left-hander gave up six hits, no walks, and struck out seven, beating Miami for the first time in five starts.
"It's easy to let things snowball, it's easy to let things carry on," Locke said. "I settled down. I started to get more in control. I kept pounding the strike zone because good things happen when you do that."
Christian Yelich hit a two-run homer that drew Miami within 4-3 in the second. The Marlins never scored again and Locke retired the last 13 batters he faced.
"He was just persistent," Pittsburgh manager Clint Hurdle said of Locke. "It started with his confidence. He could find the (arm) slot and stay with it, (catcher) Russell (Martin) kept him in a good place to battle through the first two innings then he ran the table. It's as well as he's pitched all year."
Harrison hit a double and scored twice. He is 20 for 44 during a 10-game hitting streak, with six doubles, one triple and five home runs.
Gaby Sanchez's two-run double capped a three-run seventh that pushed the lead to 7-3.
Jeff Baker singled in a run in the first for the Marlins.
Koehler was charged with four runs in six innings while allowing five hits and four walks and striking out four. It was the second time in his last nine starts that Koehler allowed more than three runs.
"I made some good pitches early in the inning that they hit but then I started falling behind in the count and had to come in with my fastball," Koehler said. "They're a very good fastball-hitting team. You don't want to put them in fastball-hitting counts the way I did."
Russell Martin hit an RBI single in the seventh to give the Pirates a 5-3 cushion before Sanchez broke the game open with his double.
Marlins: Right-hander Jarred Cosart was scratched from his scheduled start Thursday night because of a strained left oblique muscle. Cosart felt discomfort in his side while playing catch Wednesday and the Marlins decided to have him skip a start. He is tentatively scheduled to pitch next Tuesday against St. Louis. The Marlins got Cosart last week in a trade with Houston. He made his Miami debut the next day and took the loss against Cincinnati, giving up four runs in 5 1/3 innings Friday. He was 9-7 with a 4.41 ERA with the Astros. . Reliever Kevin Gregg is expected to have surgery to remove bone chips from right elbow and miss the remainder of the season. . Right-hander Henderson Alvarez played catch before the game, the first time he had thrown since going on the disabled list July 30 with right shoulder inflammation. He is expected to be activated Aug. 15, the first day he is eligible.
Pirates: Center fielder Andrew McCutchen missed his second straight game because of a fracture and cartilage damage in his lower left rib cage but remains hopeful of avoiding the disabled list. . Second baseman Neil Walker sat out for the third time in four games because of lower back tightness but is expected to return to the lineup Thursday. . Right-hander Gerrit Cole, will make a third rehab start for Triple-A Indianapolis with the date to be determined after he has a bullpen session Thursday. Cole has been on the DL since July 5 with a strained right lat.
Marlins: Rookie left-hander Brian Flynn (0-0, 6.00) will fill in for Cosart and start in the finale of the three-game series. Flynn was recalled from Triple-A New Orleans on Tuesday when right-hander Jacob Turner was designated for assignment. Flynn pitched once for the Marlins this season, allowing two runs in three innings June 27 against Oakland.
Pirates: Right-hander Edinson Volquez (8-7, 3.91) is 5-0 with a 1.99 ERA in six career starts against the Marlins and looks to snap his three-start winless streak, which comes on the heels of a four-start winning streak.