как удалить строку, содержащую строку из файла в Unix или Solaris - PullRequest
1 голос
/ 14 марта 2011

У меня есть мой файл следующим образом

test1    
test2    
test3    
test4    
test5

Я хочу удалить строку, содержащую test2, поэтому я использовал команду следующим образом, но вместо удаления только строки 'test2' он удалил весь файл и fize-size стал равным нулю.

bash# cat /aaa/bbb/ccc/myfile | sed -e '/test2/ d'  > /aaa/bbb/ccc/myfile     
bash# ls -l total 0    
-rw-r--r--   1 root     root           0  3月 11 17:41 myfile

Кто-нибудь может подсказать, что не так в команде?

Ответы [ 10 ]

7 голосов
/ 14 марта 2011

, если у вас нет GNU sed (с опцией "-i"), и вы используете Solaris, так что, вероятно, у вас нет выбора, кроме как записать во временный файл:

sed -e '.....' infile > infile.tmp
mv infile.tmp infile

обновление: отредактируйте файл на месте с помощью ed

printf "%s\n" 'g/test2/d' w q | ed infile
5 голосов
/ 14 марта 2011

Я не знаю, является ли Perl стандартным для Solaris. Если это так, вы можете использовать:

perl -ni -e 'if(!/test2/){print;}' myfile
2 голосов
/ 17 марта 2011

Вы можете просто использовать старый добрый редактор:

echo "/test2
d
w
q" | ed /aaa/bbb/ccc/myfile
1 голос
/ 16 марта 2011

Попробуйте

grep -v test2 test.txt  > temp
mv temp test.txt 
1 голос
/ 14 марта 2011

Solaris, при условии, что вы не используете архаичную версию, должен уже иметь по крайней мере bash 3. Так что, используя просто bash

while read -r line
do
  case "$line" in
     *"test2"*) continue;;
     *) echo "$line";;   
  esac
done < file > temp && mv temp file
1 голос
/ 14 марта 2011

Вы также можете использовать grep:

> grep -v test2 test.txt 
test1    
test3    
test4    
test5

Имейте в виду, что, как и в случае sed, вам не следует перезаписывать файл, из которого вы читаете, поэтому вы можете вызвать его следующим образом:

grep -v test2 test.txt> test.out

1 голос
/ 14 марта 2011

К сожалению, перенаправление вывода сразу очищает выходной файл.Поэтому вы должны использовать другой файл в качестве выходного файла, например:

sed '/test2/d' /aaa/bbb/ccc/myfile > /aaa/bbb/ccc/myfile2

Или вы можете сделать, например, что-то вроде этого:

sed '/test2/d' /aaa/bbb/ccc/myfile | tee /aaa/bbb/ccc/myfile

Но из-за буферизации это не очень надежно,Если программа вывода (tee) запишет в файл до того, как sed закончит чтение, это приведет к повреждению данных.Возможно, вы также можете поэкспериментировать с программами buffer или mbuffer вместо tee, где вы можете указать размеры буфера.Но у меня не было надежного успеха в быстром испытании.

0 голосов
/ 01 января 2014
$touch myfile

$printf "test1\ntest2\ntest3\ntest4\ntest5\n">myfile

$cat myfile 

test1
test2
test3
test4
test5

$sed '2d' myfile

test1
test3
test4
test5

Так что используйте:

$sed '2d' myfile
0 голосов
/ 14 марта 2011

Вы можете прочитать весь файл в массив в AWK:

awk '!/test2/ {a[++c] = $0} END {for (i=1; i<=c; i++) print a[i] > FILENAME}' /aaa/bbb/ccc/myfile

Поскольку перенаправление не выполняется оболочкой, раннее усечение не выполняется.

0 голосов
/ 14 марта 2011

следующий код отлично подходит для меня ...

touch myfile2
cp /aaa/bbb/ccc/myfile myfile2
sed '/test2/d' myfile2 > /aaa/bbb/ccc/myfile
...