Nguyễn Duy
Nguyễn Duy

Reputation: 93

Unix piping and redirection

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

Answers (2)

sat
sat

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

devnull
devnull

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

Related Questions