В дополнение к наблюдению, что вы можете использовать флаг -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 вы могли точно заполнить несколько командных буферов файлами, но гораздо более вероятно, что файлов вообще не будет.
Использование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
Используя 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
С GNUsed
:
sed 'h; s/puppies/bunnies/g; T; s/I/You/; G' < your-file
Использование редактора 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
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 }
'