13

У меня есть файл

xyz... rsync: "/home/path/to/file": Permission denied (13) rsync:
"/home/path/to/file1": Permission denied (13) rsync:
"/home/path/to/file2": Permission denied (13) rsync:
"/home/path/to/file3": Permission denied (13)

Теперь я хочу извлечь только пути к файлам и сохранить их в другом файле. Выходной файл выглядит так:

/home/path/to/file 
/home/path/to/file1 
/home/path/to/file2
/home/path/to/file3

Используя sed или awk, как я могу это сделать?

Я пробовал sed -n '/"/,/"/p' myfile но он не работает.

4 ответа4

17

Вы можете передать stderr вашей команды rsync в скрипт awk:

awk -F '"' '{print $2}' 

Или к команде сокращения как это:

cut -d'"' -f2
6

Используя sed:

sed 's/^[^"]*"\([^"]*\)".*/\1/'

Это ищет: начало строки, серию не-кавычек, двойную кавычку, захватывает серию не-кавычек, двойную кавычку и все остальное в строке и заменяет ее захваченным материалом.

$ sed 's/^[^"]*"\([^"]*\)".*/\1/' <<'EOF'
> xyz... rsync: "/home/path/to/file": Permission denied (13) rsync:
> "/home/path/to/file1": Permission denied (13) rsync:
> "/home/path/to/file2": Permission denied (13) rsync:
> "/home/path/to/file3": Permission denied (13)
> EOF
/home/path/to/file
/home/path/to/file1
/home/path/to/file2
/home/path/to/file3
$

Протестируйте RHEL 5 Linux с GNU sed , но только с использованием функций, которые работали бы в седьмой версии sed UNIX ™.

Кстати, немного более простой способ сделать это с помощью двух замещающих команд; изменить все, вплоть до первой двойной кавычки, включая пустую строку (это последовательность из нуля или более не кавычек, за которыми следует двойная кавычка); измените все после того, что сейчас является первой двойной кавычкой, на ничто:

sed 's/^[^"]*"//; s/".*//'

Кстати, команда, которую вы пробовали (`sed -n '/"/,/"/p'), печатает из одной строки, содержащей двойные кавычки, в следующую строку, содержащую двойные кавычки, без редактирования строк вообще. Вот почему, похоже, это не сработало для вас - оно сделало то, что вы просили, но то, что вы просили сделать, было не тем, что вы намеревались просить это сделать.

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

0

Если ваша версия grep поддерживает Perl-regexp:

grep -oP '(?<=")/home/.*?(?=")' file >> anotherfile

Результаты:

/home/path/to/file
/home/path/to/file1
/home/path/to/file2
/home/path/to/file3

Вы также можете сделать это менее строгим, чтобы соответствовать чему-либо между двойными, если вы хотите:

grep -oP '(?<=")[^"]*' file >> anotherfile
-1

Используйте оператор >>, чтобы сохранить любой вывод в файл.

подобно

grep -r "pattern" * >> file.txt

Так что просто измените это для вашего конкретного сценария, используя sed, добавив

>> filename

в команду

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .