Добавьте set -v
к вашей функции, и вы увидите, что происходит:
$ f (){ set -v; sudo -- sh -c "cd /tmp; echo \"$@\""; }
$ f 1 2
+ sudo -- sh -c 'cd /tmp; echo "1' '2"'
Что происходит? Использование вами $@
привело к созданию двух строк, заключенных в одинарные кавычки cd /tmp; эхо "1
и 2"
. Вы можете использовать $*
, если не хотите этого разбиения. См. раздел справочной страницы bash в Специальные параметры:
@ ... Когда расширение происходит в двойных кавычках, каждый параметр расширяется до отдельного слова. ... Если ... в слове расширение первый параметр соединяется с начальной частью исходного слова, и расширение последнего параметра соединяется с последней частью исходное слово.
Таким образом, в вашем случае одна строка (или слово) «xxx$@yyy» расширяется до двух строк «xxx1» и «2yyy». Вы можете проверить это, используя set -- 1 2 3
, чтобы установить $@
, а затем использовать printf ">%s<" "$@"
, чтобы увидеть количество слов, которое становится "$@"
(поскольку printf будет повторять формат для каждого аргумента):
$ set -- 1 2 3
$ printf ">%s< " "x$@y"
>x1< >2< >3y<
$ printf ">%s< " "x$*y"
>x1 2 3y<
Если вы хотите передать аргументы команде sh -c
один хак состоит в том, чтобы поместить их после одиночной команды в качестве аргументов, но это может работать не во всех оболочках:
f (){ set -v; sudo -- sh -c 'cd /tmp; echo "$@"' sh "$@"; }
f 1 2
+ sudo -- sh -c 'cd /tmp; echo "$@"' sh 1 2
Дополнительный аргумент sh
связан с тем, что первый аргумент принимается оболочкой как имя процесса.
Используя sed
,
sed '/888/d' filename
Вы можете использовать, -i
опцию для редактирования файла на месте, как,
sed -i.bak '/888/d' filename
Примечание : .bak
сохранит резервную копию оригинального файла.
Предположим, вы хотите избавиться от строк, содержащих 888
в определенном столбце, тогда вам нужно использовать,
awk -F"," '$4 != "888"' filename
IMO, использование printf
для передачи команд в ed
лучше, чем sed -i
.
printf '%s\n' 'g/,888,/d' 'w' | ed -s msalik.txt
Первый аргумент в printf
указывает ему печатать каждый оставшийся аргумент, разделенный новыми строками (\n
).
Ни один из двух последних аргументов не нуждается в кавычках. Я просто привел их в качестве примера - некоторые команды ed
нужно будет заключать в кавычки.
Почему ed
лучше, чем sed -i
?
В отличие от ed
, sed -i
не выполняет правку на месте. Он создает временный выходной файл, а затем переименовывает его поверх исходного. Это имеет два потенциально нежелательных побочных эффекта:
Разрешения на файл могут измениться из-за umask
, с которым был создан временный файл. Даже право собственности или группа могут измениться, если сценарий sed -i
будет запущен другим пользователем (который, конечно, имеет соответствующий RW-доступ к файлу и dir).
Заменяющий файл будет иметь другой inode. Это приведет к нарушению жестких ссылок.
Используя grep
grep -vw '888' infile.csv > outfile.csv
Если вы хотите редактировать на месте,
sed -i.bak '/\b888\b/d' infile.csv
Edit:
Чтобы удалить строки, содержащие 888
только в 4-м столбце
sed -i.bak -r '/^(([^,]+,){3})888,/d' infile.csv