Użyj sed zamiast zmiennej pliku zamiast pliku


30

Powiedziano mi, że było to możliwe, ale bez jednego działającego przykładu, który sedmoże odczytać zmienną łańcuchową bez potrzeby pliku wejściowego. Muszę go jeszcze uruchomić. Dla ogólnego bezpieczeństwa piszę $PATHzmienną do innej zmiennej, ponieważ mam z tym problem, ponieważ nie potrzebuję innych problemów, dopóki nie będę wiedział, jak to zrobić.

Rozważ następujące:

~$x=$PATH
~$sed -i 's/:/ /g' $x

to się nie powiedzie z: Brak takiego pliku lub katalogu.

Oto kilka innych, które próbowałem:

~$ sed -i 's/:/ /g' | (read x) 
sed: no input files
~$ sed -i 's/:/ /g' | (read $x) 
bash: read: `/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games': not a valid identifier
sed: no input files
~$ sed -i 's/:/ /g' | $(read x) 
sed: no input files
~$ sed -i 's/:/ /g' | $(read $x) 
bash: read: `/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games': not a valid identifier
sed: no input files
~$ sed -i 's/:/ /g' < $(read $x) 
bash: read: `/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games': not a valid identifier
bash: $(read $x): ambiguous redirect
~$ sed -i 's/:/ /g' < read $x 
bash: read: No such file or directory
~$ sed -i 's/:/ /g' < (read x) 
bash: syntax error near unexpected token `('
~$ sed -i 's/:/ /g' < $((read x)) 
bash: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games: syntax error: operand expected (error token is "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games")
~$ sed -i 's/:/ /g' < $((read $x)) 
bash: read /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games: division by 0 (error token is "usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games")
~$ sed -i 's/:/ /g' << $((read $x)) 
> ;^C
~$ sed -i 's/:/ /g' << $(read $x)
> ;^C
~$ sed -i 's/:/ /g' $x
sed: can't read /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games: No such file or directory
~$ sed -i 's/:/ /g' < $x
bash: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games: No such file or directory
~$ sed -i 's/:/ /g' < echo $x
bash: echo: No such file or directory
~$ sed -i 's/:/ /g' |  echo $x
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
sed: no input files

Czy to w ogóle może działać? Wolałbym nie pisać niepotrzebnych plików, aby móc korzystać z sed. W tym konkretnym przykładzie, gdyby ~$x=$PATH ~$sed -i 's/:/ /g' $xrzeczywiście działał tak, jak chciałbym, uzyskałbym:

/usr/local/sbin /usr/local/bin /usr/sbin /usr/bin /sbin /bin /usr/games /usr/local/games

który mógłbym następnie przypisać do zmiennej i użyć w przyszłych poleceniach, takich jak ls $x


1
x=$(echo "$x" | sed 's/:/ /g')?
heemayl

Odpowiedzi:


16

Może:

~$ x="$PATH"
~$ x="$(echo $x | sed 's/:/ /g')"
~$ echo "$x"
/usr/local/bin /usr/bin /bin /usr/local/games /usr/games

@ jOh --- zauważ, że sedtutaj nie działa „zmienna łańcuchowa” (?), ale standardowe wejście --- tak właśnie powinno być.
Rmano,

myślę, że źle
zwrócę się

4
@ j0h to nie ma nic wspólnego sed, jest to pytanie, w jaki sposób powłoka przekierowuje dane wejściowe. sedzajmuje się strumieniami wejściowymi i odczytuje je przez standardowe wejście. Nie ma znaczenia, czy będą to pliki, czy nie. Potrafi zaakceptować wszystko, o ile przechodzi przez standardowe wejście.
terdon

38

Nie ma to nic wspólnego z sedtym, dotyczy każdego programu, który odczytuje standardowe dane wejściowe. W każdym razie to, czego szukałeś, to

sed 's/:/ /g' <<<"$PATH"

Nie ma powodu, aby zapisywać w innej zmiennej, nic, co zrobisz w ten sposób, nie wpłynie na wartość przechowywaną w zmiennej. Potrzebujesz do tego operatora przypisania ( =). Użyta powyżej składnia nazywa się „ciągiem tutaj” i jest specyficzna dla bash, ksh i zsh. Służy do przekazywania wartości zmiennej jako danych wejściowych do programu, który odczytuje ze standardowego wejścia.

Napisałem odpowiedź na temat U&L, która zawiera listę wszystkich różnych operatorów powłok, takich jak ten. Możesz rzucić okiem.

Pamiętaj, że mógłbyś to zrobić

echo "$PATH" | sed 's/:/ /g' 

Wreszcie, naprawdę nie potrzebujesz seddo tego wcale. Możesz zrobić wszystko bezpośrednio w bash:

echo "${PATH//:/ }"

Powyżej jest konstrukcją zastępczą bash. Biorąc pod uwagę zmienną $var, wzór pati zastępstwo ( rep), aby zastąpić wszystkie wystąpienia patz rep, zrobiłbyś

echo "${var//pat/rep}"

To samo z jednym ukośnikiem zastępuje tylko pierwsze wystąpienie:

echo "${var/pat/rep}"

2
Dzięki za „konstrukcję zastępującą bash”. Byłem w stanie użyć: „$ {1 / from / to}” w funkcji Bash, aby zmienić pierwszy argument na kolejne parametry.
AAAfarmclub
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.