if ($mystr:q =~ *'\
'*) echo yes
should work in some implementations and versions of csh
(like the csh
and tcsh
ones found on Debian). In some others (like the one found on Solaris 10), you may have better luck with
set nl = '\
'
if ($mystr:q =~ *$nl:q*) echo yes
Most people have given up trying to write reliable scripts with csh
by now. Why would you use csh
in this century?
This code works for me (outputs no
) in tcsh 6.17.00 (Astron) 2009-07-10 (x86_64-unknown-linux) options wide,nls,dl,al,kan,rh,color,filec
set mystr = '1234ABC\
-------\
FOOBAR'
if ($mystr:q !~ *'\
'*) then
echo yes
else
echo no
endif
Note that if you do:
set var = `some command`
csh
stores each word (blank separated) of the output of some command
in several elements of the var
array.
With:
set var = "`some command`"
it stores each non-empty line in elements of the array.
It looks like one cannot1 store the output of a command whole into a variable in (t)csh
, so your only option would be:
set var = "`some command`" # note that it removes the empty lines
if ($#var == 1)...
1 Strictly speaking, that's not true, one could do something like:
set x = "`some command | paste -d. /dev/null -`"
set var = ""
set nl = '\
'
foreach i ($x:q)
set i = $i:s/.//:q
set var = $var:q$i:q$nl:q
end
(of course, it may not work in all csh
implementations/versions)
To insert the text j
into the variable text
at position p
(counting from zero):
p=5
text="$(seq 10)" ## arbitrary text
text="${text:0:p}j${text:p}"
To insert the text j
before the matching portion in $match
:
text="${text%%${match}*}j${match}${text##*${match}}"
This pulls off the leading portion of $text
until it finds $match
, then adds the j
, then the $match
, then the trailing portion of $text
until it finds $match
. Hopefully there's only one match of $match
in $text
!
Best Answer
Note that except in zsh, shell variables cannot store arbitrary sequences of bytes. Variables in all other shells can't contain the NUL byte. And with the
yash
, they can't contain bytes not forming valid characters.For files that don't contain NUL bytes, in POSIX-like shells, you can do:
We add a
.\n
and strip the trailing.
to work around the fact that$(...)
strips all trailing newline characters.The above would also work in
zsh
for files that contain NULs though inzsh
you could also use the$mapfile
special associative array:In zsh or bash, you can also use:
That reads up to the first NUL byte. It will return a non-zero exit status unless a NUL byte is found. We use the command group here to be able to at least tell the errors when opening the file, but we won't be able to detect read errors via the exit status.
Remember to quote that variable when passed to other commands. Newline is in the default value of
$IFS
, so would cause the variable content to be split when left unquoted in list contexts in POSIX-like shells other than zsh (not to mention the other problems with other characters of$IFS
or wildcards).So:
for instance (not
, certainly notprintf %s $var
which would addecho $var
echo
's problems in addition to the split+glob ones).With non-POSIX shells:
Bourne shell:
The bourne shell did not support the
$(...)
form nor the${var%pattern}
operator, so it can be quite hard to achieve there. One approach is to useeval
and quoting:With
(t)csh
, it's even worse, see there.With
rc
, you can use the``(separator){...}
form of command substitution with an empty separator list: