Chcę zrobić:
cat update_via_sed.sh | sed 's/old_name/new_name/' > new_update_via_sed.sh
w moim programie.
Ale chcę użyć zmiennych, np
old_run='old_name_952'
new_run='old_name_953'
Próbowałem ich użyć, ale podstawienie się nie zdarzyło (bez błędu). Próbowałem:
cat update_via_sed.sh | sed 's/old_run/new_run/'
cat update_via_sed.sh | sed 's/$old_run/$new_run/'
cat update_via_sed.sh | sed 's/${old_run}/${new_run}/'
Odpowiedzi:
Mógłbyś:
Ale uważaj, że
$old_run
byłoby to traktowane jako wyrażenie regularne, a więc wszelkie znaki specjalne, które zawiera zmienna, takie jak/
lub.
musiałyby być poprzedzane znakami ucieczki . Podobnie, w$new_run
, znaki&
i\
musiałyby być traktowane specjalnie, a ty musiałbyś uciec od/
znaków nowej linii.Jeśli zawartość
$old_run
lub$new_run
nie jest pod twoją kontrolą, bardzo ważne jest, aby wykonać ucieczkę, lub w przeciwnym razie kod stanowi lukę w zabezpieczeniach polegającą na wstrzykiwaniu kodu .źródło
sed
sam nie użyje wyrażenia regularnego, alesed -E
zrobiłby to?-e
jest określeniesed
e Xpression , więc można przekazać więcej niż jeden (jak wsed -e exp1 -e exp2
) lub kombinacje plików i wyrażeń (sed -f file -e exp
). Być może mylisz się z tym,-E
co z niektórymi implementacjami, mówi sedowi, aby używał ERE zamiast BRE.-E
opanowania tylko rozszerzonego wyrażenia regularnego, a nie zwykłego. Dzięki za wyjaśnienie.sed
implementacje dla jeszcze większej składni wyrażeń regularnych.To działało:
Ponieważ chcę „ponownie wykorzystać” ten sam plik, faktycznie używam tego dla każdego, kto chce mieć podobne podejście:
Powyższe utworzyło nowy plik, a następnie usuwa bieżący plik, a następnie zmienia nazwę nowego pliku na bieżący.
źródło
sed -i s/"$old"/"$new"/ update_via_sed.sh
. Należy jednak pamiętać, że nie działa to dla żadnej wartości starej i nowej. np. nie może zawierać / itp., ponieważ $ old jest nadal wyszukiwaniem, a $ new wzór zastępczy, w którym niektóre znaki mają specjalne znaczenie.sed -i "s/$old/$new/"
jest również w porządku (z powyższymi środkami ostrożności).sed
zwykle uważa, że separator jest pierwszym znakiem pos
poleceniu - tzn. jeśli twoje zmienne zawierają ukośniki,/
ale nie pozwalają na powiedzmy w (@
), możesz użyć „s @ $ old @ $ new @”.Możesz używać zmiennych w sed, o ile są one w podwójnym cudzysłowie (nie w jednym cudzysłowie):
Jeśli masz
/
zmienną ukośnik ( ) w zmiennej, użyj innego separatora, jak poniżejźródło
|
jak w moim przypadku, zmienne zawierają ścieżkę, więc ona ma/
w sobie|
działał dla mnie w systemie MacOS 10.14, ale inni separatorzy lubią@
lub#
nie. Miałem też ukośniki w env var.odpowiedzią był „in-place” sed (użycie flagi -i). Dzięki Peterowi.
źródło
s@
(co w żaden sposób nie jest wyjątkowe dla powłoki). Najlepiej jest umieścić wszystko w cudzysłowiesed -i "s@$old@$new@" file
. Pamiętaj, że-i
nie jest to standardowased
opcja.$
w tym poleceniu. Podobnie, zamierzam zmienić$xxx
jako całość wartość zmiennej$JAVA_HOME
. Próbowałemsed -i "s@\$xxx@$JAVA_HOME@" file
, ale błąd mówino previous regular expression
man bash
daje to o pojedynczym cytowaniuCokolwiek wpiszesz w wierszu poleceń, bash interpretuje to, a następnie wysyła wynik do programu, do którego ma zostać wysłany. W tym przypadku, jeśli użyjesz
sed 's/$old_run/$new_run/'
, bash najpierw zobaczysed
, rozpoznaje go jako plik wykonywalny obecny w$PATH
zmiennej . Pliksed
wykonywalny wymaga danych wejściowych. Bash szuka danych wejściowych i znajduje's/$old_run/$new_run/'
. Pojedyncze cytaty mówią bash, aby nie interpretować zawartych w nich treści i przekazać je takimi, jakie są. Więc bash następnie podaje je sed. Sed podaje błąd, ponieważ$
może wystąpić tylko na końcu linii.Zamiast tego, jeśli użyjemy podwójnych cudzysłowów, tj.
"s/$old_run/$new_run/"
Wtedy bash widzi to i interpretuje$old_run
jako nazwę zmiennej i dokonuje podstawienia (ta faza nazywana jest rozszerzaniem zmiennej). Właśnie tego wymagaliśmy.Ale musisz zachować ostrożność, używając podwójnych cudzysłowów, ponieważ są one interpretowane najpierw przez bash, a następnie podawane do sed. Dlatego niektóre symbole, takie jak `, muszą być poprzedzone znakami ucieczki.
źródło
Ryzykujesz nieposłuszeństwo - czy zastanawiałeś się
perl
.Co - między innymi - jest całkiem dobre w wykonywaniu operacji w stylu „sed”, ale także w pełni funkcjonalnym zagadnieniu programistycznym.
To wygląda jak w przykładzie, co ty właściwie próbuje zrobić, to zwiększyć liczbę.
Co powiesz na:
lub jako jedna wkładka - styl sed:
źródło
W
$d1
przechowuję wartościNie mogę zastąpić wartości zmiennej, więc wypróbowałem następujące polecenie, które działa
brak podwójnego cudzysłowu w
"${d1}"
tym był błądźródło
Założono
$old_run
i$new_run
są już ustawione:Pokazuje zmianę na ekranie. W razie potrzeby możesz przekierować dane wyjściowe do pliku.
źródło
Aby użyć zmiennej w sed, użyj podwójnych cudzysłowów „”, aby zamknąć zmienną we wzorcu, którego używasz. Na przykład: a = „Cześć” Jeśli chcesz dołączyć zmienną „a” do wzoru, możesz użyć poniższego: sed -n „1, / pattern” $ {a} „pattern / p” nazwa pliku
źródło
$a
nie jest tutaj cytowane, co oznacza, że wszelkie spacje w jego wartości będą wywoływały dzielenie słów w powłoce.Możesz także użyć Perla:
źródło
""
) nic nie zrobią.przerwać ciąg
bad => linux zobacz ciąg $ old_run:
good => linux zobacz zmienną $ old_run:
źródło
$old_run
lub$new_run
zawiera spacje?