Reputation: 93
Assume you want to read as input the file ‘passwords.txt’, change every uppercase letter to a lowercase letter and every ‘$ ’ to a ‘# ’, then save the result back to that same file (overwriting it). How would you do this with the tr command? HINT: Use piping and file redirection.
I tried these 2 commands, but they didn't work. I think the file got truncated by the system, so that the passwords.txt becomes empty after.
cat passwords.txt | tr '[A-Z'!']' '[a-z'#']'
tr ‘[A-Z"!"]’ ‘[a-z"#"]’ < passwords.txt > passwords.txt
I know we can do something like writing it to a temp file and use "&&" to change the temp file name to passwords.txt . However, this is a homework problem and we haven't learn about "&&" yet, so I believe that there must be another way to do this with just piping and redirecting only.
Upvotes: 0
Views: 118
Reputation: 14969
Here is another way without using &&
,
echo "$(tr '[A-Z$]' '[a-z#]' < sample)" > sample
Test:
sat:~# cat > sample
sample TEXT
$test
sat:~#
sat:~# echo "$(tr '[A-Z$]' '[a-z#]' < sample)" > sample
sat:~# cat sample
sample text
#test
sat:~#
Upvotes: 1
Reputation: 123628
I think the file got truncated by the system, so that the passwords.txt becomes empty after.
You are correct. You'd need to redirect the tr
output to a temporary file and move the temporary file to the original one.
Moreover, the use of quotes around !
(I assume that it was intended to be $
) and #
is superfluous. You could say:
cat /etc/passwd | tr 'A-Z$' 'a-z#' > temp && mv temp /etc/passwd
or eliminate the useless use of cat
by using indirection:
tr 'A-Z$' 'a-z#' < /etc/passwd > temp && mv temp /etc/passwd
Here &&
is a control operator separating two commands. If you say:
command1 && command2
then command2 is executed if, and only if, command1 returns an exit status of zero, i.e. if command1 is successful.
Upvotes: 1