Повторяющиеся строки, содержащие строку с правками

В дополнение к наблюдению, что вы можете использовать флаг -Rдля chown, причина, по которой вы получаете сообщение об ошибке, почти наверняка[1] связана с тем, что у вас нет файлов, которые нужно изменить. В версии gnu xargsесть дополнительный флаг -r, указывающий xargs не запускать команду, если для команды нет ввода.

Однако использование xargsявляется неправильным подходом, POSIX-версия findбудет группировать команды для вас. Используйте

find. \( ! -user root -o ! -group users \) -exec chown -vc root:users {} +

обратите внимание на конечную +, а не на часто встречающуюся \;в примерах использования -exec. С \;команда запускается один раз для каждого соответствующего файла, но с +файлы группируются и запускаются пакетами.

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

[1] В зависимости от реализации xargs вы могли точно заполнить несколько командных буферов файлами, но гораздо более вероятно, что файлов вообще не будет.

-4
25.02.2021, 11:14
5 ответов

Использованиеawk:

awk 'function prnt() { print edit ORS hold; hold=edit="" }
     hold            { prnt() }
     /puppies/       { hold=$0; $1="you"; gsub("puppies", "bunnies"); edit=$0; next }
END{ if(hold) prnt() }1' infile
1
18.03.2021, 22:28

Используя sedи предполагая, что триггером является подстрока cuteв конце строки:

sed '/cute[[:blank:]]*$/ { h; s/^I/You/; s/[[:alpha:]]* cute/bunnies cute/; G; }' file

[[:blank:]]*в шаблоне позволяет использовать пробелы или табуляции в конце строки (первая строка имеет завершающий пробел в вопросе ).

Это даст текст

You have bunnies cute
I have puppies cute
I have two kitties
You have three bunnies cute
I have three puppies cute
I have four kitties

Команда hсохраняет копию текущей строки в «резервном пространстве». Первая команда s///изменяет Iв начале строки на You, а вторая изменяет любое слово, предшествующее cute, на bunnies. Наконец, команда Gдобавляет исходную строку из пробела в конец текущей (модифицированной )строки с символом новой строки в -между ними.


Вариант:

sed '/[[:alpha:]]* \(cute[[:blank:]]*\)$/ { h; s//bunnies \1/; s/^I/You/; G; }' file

При этом используется тот факт, что если оставить регулярное выражение пустым в команде s///, используется самое последнее регулярное выражение.


Вариант, который запускается строкой puppies, а не cute.Это делает его немного короче:

sed '/puppies/ { h; s//bunnies/; s/^I/You/; G; }' file
1
18.03.2021, 22:28

С GNUsed:

sed 'h; s/puppies/bunnies/g; T; s/I/You/; G' < your-file
1
18.03.2021, 22:28

Использование редактора sed :

sed -e '
  h;/puppies/G
  s//bunnies/
  /\n/s/^I/You/
' file

Альтернативно с awk

awk '{h=$0}
  sub(/puppies/, "bunnies") {
    sub(/^I/, "You")
    $0 = $0 ORS h
  };1
' file
0
18.03.2021, 22:28

gnu sed сbranches:

sed '
s/puppies/&/g; tfind
n
:find 
    h
    s/puppies/bunnies/g
    s/^I/You/
    G
'

gawk:

awk '$0~/puppies/ {

 original=$0
 sub(/puppies/, "bunnies")
 sub(/^I/, "You")
 print $0, original
 next
} 
{ print }
'
0
18.03.2021, 22:28

Теги

Похожие вопросы