Как заменить второе вхождение пробела в каждой строке на «sed» или «awk»?

#regex #awk #sed

Вопрос:

У меня есть файл hashes , в котором много строк, которые выглядят так:

 wget https://ipfs.io/ipfs/QmbKi6XiMmf4YfvKXhqVPymD1HDwJ3WqukjyLuEvnrZrCz The_Supremes_-_My_World_Is_Empty_Without_You_(lyrics).mkv
 

Все линии внутри hashes будут следовать шаблону:

 wget https://ipfs.io/ipfs/hashthatis46characterlong nameOfAfileWithoutSpaces
 

как они написаны моим сценарием со следующими строками кода:

 find ~/pCloudDrive/VisualArts/Films/Fiction_Movies -maxdepth 1 -type f -size  200M -exec ipfs add --nocopy {} ;>>~/CS/ipfs/hashes amp;amp; 
sed -i 's;added ;wget https://ipfs.io/ipfs/;g' ~/CS/ipfs/hashes
 

Все хэши будут состоять из 46 символов и обычно начинаются с «Qm», но в будущем это может быть не обязательно.

Я хочу заменить второй пробел в каждой строке этого файла на «- O», чтобы он выглядел так:

 wget https://ipfs.io/ipfs/hashthatis46characterlong -O nameOfAfileWithoutSpaces
 

Я пытался sed 's/[0-9A-z]{46,46}s/amp; -O /g' hashes , но безрезультатно — я получаю следующий результат:

 sed: -e expression #1, char 27: Invalid range end
 

Как мне это сделать? Было awk бы лучшим решением этой проблемы, чем sed ?

Ответ №1:

Использование GNU awk и gensub() изменение второго вхождения в каждой записи:

 $ awk '{print gensub(/ /," -O ","2")}' file
 

Например:

 $ echo 1 2 3 4 5  | awk '{print gensub(/ /," -O ","2")}'
1 2 -O 3 4 5
 

Ответ №2:

Так просто, как это

 sed 's/ / -O /2' input
 

где конец 2 в команде sed означает «второе вхождение».

Ответ №3:

Как у вас nameOfAfileWithoutSpaces есть , желаемый результат можно получить другим способом, используя GNU sed , а именно:

 s/([^[:space:]]*)$/-O 1/
 

это действительно захватывает символы без пробелов, за которыми следует конец строки ( $ ), а затем заменяет -O их следующими этими символами. Я протестировал в использовании sed.js.org и для ввода

 wget https://ipfs.io/ipfs/hashthatis46characterlong nameOfAfileWithoutSpaces
wget https://ipfs.io/ipfs/hashthatis46characterlong anotherName
 

выход есть

 wget https://ipfs.io/ipfs/hashthatis46characterlong -O nameOfAfileWithoutSpaces
wget https://ipfs.io/ipfs/hashthatis46characterlong -O anotherName
 

Ответ №4:

Другой awk :

 $ awk '{$3="-O" OFS $3}1' file