Подстановочный знак в команде sed для замены строки не работает - PullRequest
0 голосов
/ 10 мая 2019

Я пытаюсь использовать команду sed в терминале, чтобы заменить определенную строку во всех моих текстовых файлах с определенным расширением определенной строкой:

sed -i.bak '35s/^.*$/5\) 1\-4/' fitting_file*.feedme

Поэтому я пытаюсь заменить строку 35 в каждом из этих файлов строкой "5) 1-4". Когда я запускаю команду ls fitting_file*.feedme | wc -l в этом каталоге, я получаю 221 файл. Однако когда я запускаю указанную выше команду sed, она редактирует только ПЕРВЫЙ файл в порядке ls fitting_file*.feedme. Я знаю это, потому что grep '5) 1-4' fitting_file*.feedme постоянно возвращает первый файл в списке только после того, как я запустил команду замены. Я также попытался заменить fitting_file*.feedme на разделенный пробелами список из пары этих файлов в моей команде sed в качестве теста, но он все еще работал только с тем, который я выбрал для первого списка. Почему это происходит?

Ответы [ 3 ]

0 голосов
/ 10 мая 2019

Попробуйте

Создайте файл, содержащий вашу инструкцию sed, как это

#!/bin/bash 
sed -i.bak '35s/^.*$/5\) 1\-4/' $1
exit 0

и назовите его прог.ш. Затем сделайте его исполняемым:

chmod u+x prog.sh

теперь вы можете решить вашу проблему, используя

find . -name fitting_file\*.feedme -exec ./prog.sh {} \;

Вы можете сделать все это в одной строке, но, честно говоря, количество требуемых выходов немного больше. Удачи.

0 голосов
/ 11 мая 2019

То, что вы пытаетесь сделать, не используя цикл оболочки , это:

awk -i inplace -v inplace::suffix=.bak 'FNR==35{$0="5) 1-4"}1' fitting_file*.feedme

Обратите внимание, что в отличие от sed, который может просто считать строки во всех входных файлах, awk имеет NR для отслеживания количества записей (по умолчанию строк) во всех файлах и FNR для тех же, но только внутри текущего файла.

Выше используется GNU awk для редактирования на месте, точно так же как GNU sed имеет -i для этого. По умолчанию awk на MacOS - BSD awk, а не GNU awk, но вы должны установить GNU awk, так как он не содержит всех ошибок, которые имеет BSD awk, и имеет массу чрезвычайно полезных расширений.

Если вы просто хотите использовать awk от MacOS, тогда это будет что-то вроде:

find . -name 'fitting_file*.feedme' -exec sh -c "\
    awk 'FNR==35{\$0=\"5) 1-4\"}1' \"\$1\" > \"\$1.bak\" &&
    mv -- \"\$1.bak\" \"\$1\"
" sh {} \;

, что, очевидно, становится довольно сложным - я, вероятно, поместил бы скрипт awk + mv в файл для выполнения из sh -c или просто прибегнул бы к самому циклу оболочки, если столкнулся с этой альтернативой (или похожим кошмаром цитирования с xargs) !)

0 голосов
/ 10 мая 2019

sed работает на одноместном потоке.По сути, он объединяет все файлы вместе и обрабатывает их как один поток.Таким образом, он заменяет 35-ю строку большого каскадного потока.

Чтобы увидеть это, создайте 20-строчный файл с именем A и 20-строчный файл с именем B. Примените команду sed как

sed -i.bak '35s/^.*$/5\) 1\-4/' A B

и вы увидите замену 15-й строки B.

Я думаю, что это должно ответить на ваш прямой вопрос.Что касается того, как сделать то, что вам нравится, я предполагаю, что вы уже поняли, что перенос команды sed в for - это один из способов сделать это.:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...