Как удалить строку из файла, если строка содержит определенную строку? [дубликат]

Добавьте 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связан с тем, что первый аргумент принимается оболочкой как имя процесса.

0
23.07.2016, 02:42
3 ответа

Используя sed,

sed '/888/d' filename

Вы можете использовать, -i опцию для редактирования файла на месте, как,

sed -i.bak '/888/d' filename

Примечание : .bak сохранит резервную копию оригинального файла.


Предположим, вы хотите избавиться от строк, содержащих 888 в определенном столбце, тогда вам нужно использовать,

awk -F"," '$4 != "888"' filename
3
28.01.2020, 02:27

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. Это приведет к нарушению жестких ссылок.

0
28.01.2020, 02:27

Используя 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
0
28.01.2020, 02:27

Теги

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