I have to do below operation in one script.
/etc/passwd file to display user home directory ownership:
ls -lLd /<usershomedirectory>
I can grep the home path as following, please help me with running the ls on the home path based on the user home path that is identified using single line script.
grep "" /etc/passwd | cut -f 6 -d :
Updated
How to do it for some more ls
# ls -al /<usershomedirectory>/.login
# ls -al /<usershomedirectory>/.cschrc
# ls -al /<usershomedirectory>/.logout
# ls -al /<usershomedirectory>/.profile
# ls -al /<usershomedirectory>/.bash_profile
# ls -al /<usershomedirectory>/.bashrc
# ls -al /<usershomedirectory>/.bash_logout
# ls -al /<usershomedirectory>/.env
# ls -al /<usershomedirectory>/.dtprofile
# ls -al /<usershomedirectory>/.dispatch
# ls -al /<usershomedirectory>/.emacs
# ls -al /<usershomedirectory>/.exrc
You can use backticks/command output substitution:
ls -lLd "$(grep "^$username:" /etc/passwd | cut -f6 -d: )"
or piping to xargs:
grep "^$username:" /etc/passwd | cut -f 6 -d: | xargs -r ls -lLd
(I also added some more grep context to make sure the user matches exactly and supports blanks in file names)
The ~ expansion could be used with eval, not sure if thats a good idea:
eval "ls -lLd ~$username"
As #EtanReisner commented, the usual way to do this would be:
ls -lLd ~user
However, if you must use parsing of /etc/passwd and substitution, I would recommend this particular recipe:
ls -lLd $(awk -v acct="user" -F: '$1 == acct { print $NF-1 }' /etc/passwd)
But there's quite a few ways, as the other answer(s) will demonstrate as well...
Related
I have XYZ=/opt/Ind and certain directories under /opt/Ind
I sorted the directories by : ls -t $XYZ
Then I need to get only the size of the first folder.
I tried
du -sk $(ls -t $XYZ/TAL/ | head -n 1)
It gives me this error
du: cannot access `\033[0m\033[01;34m20160525_033732\033[0m': No such file or directory
Will be glad for the help.
The problem here is that you are not using the normal ls but an alias, so that it provides you some coloured output. This way, instead of a normal name 20160525_033732 you get it with the blue colour.
$ echo -e "\033[0m\033[01;34m20160525_033732\033[0m"
20160525_033732
Just use \ls to use the original ls without any alias.
du -sk "$(\ls -t $XYZ/TAL/ | head -n 1)"
# ^
See what the alias is with:
type ls
It will probably return something like:
ls is aliased to `ls --color=always'
add --color=never to the ls so it won't colorize the output:
du -sk $(ls --color=never -t $XYZ/TAL/ | head -n 1)
I'm trying to use the /etc/passwd file to list home directories of users in the system, sorted and without repetitions, such that nonexisting directories would not be printed..
This is my command:
cut -f 6 -d ':' /etc/passwd | sort -su | ls -ld
It acts as if I just ran ls -ld with no arguments from the command pipe at all.
You can't pipe stuff into ls.. You could do something like:
ls -ld $(cut -f 6 -d ':' /etc/passwd | sort -su)
By spawning a new bash to execute the cut | sort and passing it as a ls argument
ls does not take piped output. You could, however, use forward quotes to execute it on a list of directories:
ls `cut -f 6 -d ':' /etc/passwd | sort -su `
You could use xargs
cut -f 6 -d ':' /etc/passwd | sort -su | xargs ls
You were not far away, it was enough to add a xargs before ls :
cut -f 6 -d ':' /etc/passwd | sort -u | xargs ls -ld
I have search string in one variable ($AUD_DATE) and replace string in another variable ($YEST_DATE). I need to search file name in a folder using $AUD_DATE and then replace it with $YEST_DATE.
I tried using this link to do it but its not working with variables.
Find and replace filename recursively in a directory
shrivn1 $ AUD_DATE=140101
shrivn1 $ YEST_DATE=140124
shrivn1 $ ls *$AUD_DATE*
NULRL.PREM.DATA.CLRSFIFG.140101.dat NULRL.PREM.DATA.CLRTVEH.140101.dat
shrivn1 $ ls *$AUD_DATE*.dat | awk '{a=$1; gsub("$AUD_DATE","$YEST_DATE");printf "mv \"%s\" \"%s\"\n", a, $1}'
mv "NULRL.PREM.DATA.CLRSFIFG.140101.dat" "NULRL.PREM.DATA.CLRSFIFG.140101.dat"
mv "NULRL.PREM.DATA.CLRTVEH.140101.dat" "NULRL.PREM.DATA.CLRTVEH.140101.dat"
Actual output I need is
mv "NULRL.PREM.DATA.CLRSFIFG.140101.dat" "NULRL.PREM.DATA.CLRSFIFG.140124.dat"
mv "NULRL.PREM.DATA.CLRTVEH.140101.dat" "NULRL.PREM.DATA.CLRTVEH.140124.dat"
Thanks in advance
Approach 1
I generally create mv commands using sed and then pipe the output to sh. This approach allows me to see the commands that will be executed beforehand.
For example:
$ AUD_DATE=140101
$ YEST_DATE=140124
$ ls -1tr | grep "${AUD_DATE}" | sed "s/\(.*\)/mv \1 \1_${YEST_DATE}"
Once you are happpy with the output of the previous command;repeat it and pipe it's output to sh, like so:
$ ls -1tr | grep "${AUD_DATE}" | sed "s/\(.*\)/mv \1 \1_${YEST_DATE}" | sh
Approach 2
You could use xargs command.
ls -1tr | grep ${AUD_DATE}" | xargs -I target_file mv target_file target_file${YEST_DATE}
This takes a directory as a parameter:
#!/bin/bash
ls -l $1 |awk '$3!=$4{print $9}'
Now what I need is to be able to do ANOTHER ls -l on the just the files that are found from the awk statement.
Yeah, it sounds dumb, and I know of like 3 other ways to do this, but not with awk.
Use awk system command:
ls -l $1 |awk '$3!=$4{system("ls -l " $9)}'
The command to use is xargs.
man xargs
should give some clues.
#!/bin/bash
ls -l $1 | awk '$3!=$4{ system( "ls -l '$1'/" $9}'
If it is allowed to adjust the first ls -l you could try to do:
ls -ld "$1"/* |awk '$3!=$4{print $9}' | xargs ls -l
In this case ls will prefix the directory. But I don't know if this is portable behavior.
I'm performing this
$ ls -l | awk '{print substr($9,substr1,11)}' | uniq | xargs -i ls {}*
ls: cannot access telneter.py*: No such file or directory
ls: cannot access telnetlib.p*: No such file or directory
ls: cannot access threading.p*: No such file or directory
I meant for it to search for files files* however it tells me that it cannot find the files because its actually looking for them with the actual * but i wanted to search for all files by * and not for files ending with *.
anyone can help with this please?
thanks
The * gets in too late to be interpreted by the shell. So, do it in a subshell.
ls -l | awk '{print substr($9,substr1,11)}' | uniq | xargs -i bash -c "ls {}*"