Як отримати статус виходу при використанні команди sed?


11

grepКоманда видає статус виходу:

$echo "foo.bar" | grep -o foo
foo
$echo $?
0
$echo "foo.bar" | grep -o pop
$echo $?
1  

Але мені потрібно скористатися, sedі я зрозумів, що він не має статусу виходу:

$echo "foo.bar" | sed 's/bar.*$//'
foo.
$echo $?
0
$echo "foo.bar" | sed 's/pop.*$//'
foo.bar
$echo $?
0  

Я знаю, що мені слід пограти з -qваріантом, але мені це не вдалося.


7
Зауважте, що sedбільшість, безумовно, має статус виходу, він просто не робить те, що вам потрібно. Якщо sedкоманда не вдасться, наприклад, якщо ви спробуєте запустити її у файлі, у якого ви не маєте доступу до запису або до такого, який не існує, sedвийде зі статусом виходу не 0. Статус виходу просто вказує, чи sedвдалося виконати те, що ви йому сказали, і echo "foo.bar" | sed 's/pop.*$//'правильно виконано. Це видалено всі рядки за допомогою pop. Що таких рядків не було, не має значення, команда все-таки працювала.
тердон

@Zanna Я збирався розмістити відповідь, але відчув, що це насправді не відповідає на питання. Це лише пояснює помилкове уявлення, але не надає корисного рішення, як, наприклад, нижче. Тож коментар видався більш підходящим.
тердон

Відповіді:


13

Ви можете використовувати q n, щоб вийти зі статусом виходу n - але для того, щоб зробити це корисним, вам також потрібно буде використовувати деякі розгалуження та контроль потоку :

t
відгалуження умовно (тобто: перейти до мітки), лише якщо s/// команда успішна з моменту зчитування останнього рядка введення або взята інша умовна гілка.

Мабуть, найкраще вибрати значення для n, яке відрізняється від одного зі стандартних значень статусу виходу:

Стан виходу в нуль вказує на успіх, а ненульове значення вказує на збій. GNU 'sed' повертає такі значення помилки статусу виходу:

0
 Successful completion.

1
 Invalid command, invalid syntax, invalid regular expression or a
 GNU 'sed' extension command used with '--posix'.

2
 One or more of the input file specified on the command line could
 not be opened (e.g.  if a file is not found, or read permission is
 denied).  Processing continued with other files.

4
 An I/O error, or a serious processing error during runtime, GNU
 'sed' aborted immediately.

Так, наприклад

$ echo "foo.bar" | sed 's/bar.*$//; t; q42' ; echo $? 
foo.
0

тоді як

$ echo "foo.bar" | sed 's/baz.*$//; t; q42' ; echo $? 
foo.bar
42

Якщо ви хочете опустити друк за замовчуванням для простору візерунка, то замініть qйого Q(зверніть увагу, що Qце розширення GNU).


1

Ось як шукати регекс за допомогою sed і виділяти відповідність або повертати вихідний код (5), якщо не знайдено відповідності:

Це input.txt:

hello there
my dear old friend
a lot of things
we'll pass along the end

Ось моя функція друкувати всі + Виділити збіги + Повернути вихідний код:

highlight()
{
  pattern=$1
  shift
  sed '/'"${pattern}"'/,${s//\x1b[32m&\x1b[0m/g;b};$q5' "$@"
}

$ виділити "lo \ | кінець" input.txt || echo -e "\ n * Не знайдено відповідності *"

Хель ось там
мій дорогий старі ПТ кінець
а л т речей ,
ми будемо передавати чи нг на кінці

Якщо немає відповідності, він поверне вихідний код (5). Ви можете використовувати його з кішкою та трубою | так само:

$ cat input.txt | виділіть "гарячі \ | та" || echo -e "\ n * Не знайдено відповідності *"

привіт,
мій дорогий мій друже,
багато речей, які
ми передамо наприкінці

* Не знайдено відповідності *

Завдяки https://unix.stackexchange.com/a/405725/43233 - я використовую його + опцію sed quit.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.