Wyskakujące cytaty w aliasie zsh

12

Kontynuując pytanie dotyczące usuwania nowych linii z tekstu, chcę przekształcić to w alias zsh w następujący sposób:

alias striplines=' awk " /^$/ {print \"\n\"; } /./ {printf( \" %s \",$0);}"'

Próbowałem uciec od cytatów w skrypcie awk, ale otrzymuję ten błąd:

awk: (FILENAME=bspsrobustness FNR=1) fatal: division by zero attempted

(Plik nazywa się bspsrobustness)

Czy istnieje sposób na robienie tego, co chcę? Przypuszczam, że mógłbym zmienić to w skrypt awk zamiast w alias zsh, czy to moja najlepsza opcja?

Seamus
źródło
Nawiasem mówiąc, dotyczy to wszystkich powłok (w stylu Bourne'a, a nie csh).
Gilles „SO- przestań być zły”

Odpowiedzi:

9

Możesz użyć funkcji zsh zamiast aliasu. Bez cytatów do przeskoczenia.

striplines() {
    awk '... awk body "with quotes" ...' "$@"
}
Glenn Jackman
źródło
A jak to nazwać striplines filename:?
Seamus
czy możesz wyjaśnić, co "$@"robi?
Seamus
@Seamus, tak, nazwałbyś to dokładnie tak. "$@"Składnia wysyła się striplines argumenty awk niezakłócony - konieczne, jeśli, powiedzmy, dowolnych nazwach zawierać spacji: striplines "file 1" "file 2"by wysłał dwie nazwy plików do awk.
glenn jackman
5

Aby dowiedzieć się, co się dzieje, biegnij

% alias striplines='print -lr awk " /^$/ {print \"\n\"; } /./ {printf( \" %s \",$0);}"'
% striplines
awk
 /^$/ {print "\n"; } /./ {printf( " %s ",zsh);}

Ponieważ $znaki są w podwójnych cudzysłowach (gdy są rozwijane po rozwinięciu aliasu), są one interpretowane przez powłokę. Aby uzyskać prawidłowe cytowanie, łatwiej jest umieścić całą definicję aliasu w pojedynczych cudzysłowach. W pojedynczych cudzysłowach znajduje się to, co zostanie rozwinięte, gdy użyty zostanie alias. Teraz, gdy argument argumentu awkjest otoczony podwójnymi cudzysłowami, jasne jest, że potrzebujesz wcześniej odwrotnych ukośników \"$.

alias striplines='print -lr awk " /^\$/ {print \"\n\"; } /./ {printf( \" %s \",\$0);}"'

Przydatnym idiomem pojedynczego cudzysłowu jest ciąg znaków, który '\''jest dosłownie sposobem na umieszczenie dosłownego pojedynczego cudzysłowu w ciągu pojedynczego cudzysłowu. Technicznie istnieje zestawienie łańcucha pojedynczego cudzysłowu, cudzysłowu odwrotnego 'i innego łańcucha pojedynczego cudzysłowu. Zestawiony pusty ciąg ''na końcu można usunąć.

alias striplines='print -lr awk '\'' /^$/ {print "\n"; } /./ {printf( " %s ",$0);}'\'

Po tej długiej wyjaśnienia, zalecenie: gdy jest zbyt skomplikowane dla aliasu, użyj funkcji .

Gilles „SO- przestań być zły”
źródło