I try to copy a command from history. How can I copy the 510th command? Please, see the data below. My bet is:
history | grep 510 | sed '1q;d' | awk '{print $2-$10}' | pbcopy
but the output is 0. I cannot understand the reason. What is wrong in the command?
505 find . -perm=750 -print0 | xargs -0 chmod 750
506 find . --perm=750 -print0 | xargs -0 chmod 750
507 find . -perm=750 -print0 | xargs -0 chmod 750
508 find . -perm=750 -print0 | xargs -0 chmod 750
510 find . -perm 750 -print0 | xargs -0 chmod 750
512 history | grep perm 750 -print0 | pbcopy
If you're using bash:
echo "!510" | pbcopy
(See also "history expansion" in the bash manual)
You can use perl to print everything but the first column (510) of the requested line:
history | perl -ane 'print "#F[1..$#F]" if($F[0]==510)'
For a range of fields in Awk, you need a for-loop. What you're doing is subtraction, thus the result of zero.
Usually the cut command does the task of extracting columns, but sometimes Awk is more appropriate.
Here's what you meant.
history | grep 510 | sed 1q \
| awk '{for(i = 2; i <= NF; i++){ORS = (i == NF ? "\n" : " "); print $i;}}' \
| pbcopy
The reason is that $2 and $10 are not numbers in the awk scripts. The fields' indexes are 1-based, so if you want the 750, the first one is $5, the second one is $11.
Note that this is different with the lines with "-perm=750"
Related
I am trying to create a script which looks for x days old files that have a specific string in it, it then removes it and logs the file it has changed.
My way is probably not the best way, but I am new to this so looking for some help. I have got to a stage where the script works but it does not log the file name it has worked on
Working script is
find /home/test -mtime +5 -type f ! -size 0 | xargs grep -E -l '(abc_Pswd_[1-9])' | xargs -n1 sed -i '/abc_Pswd_[1-9].*/d'
I am trying to get the file name from 2nd part of the script I have tried few things
find /home/test -mtime +7 -type f ! -size 0 | xargs grep -E -l '(abc.1x.[1-9] )' > /home/test/tst.log| xargs -n1 sed -i '/abc_Pswd_[1-9].*/d'
This works in terms of logging the result but it exits with the error "sed: no input files"
$ echo "file_contents" > filename.txt
$ find . -type f -print0 | xargs -0 sed 's/file//g'
_contents
How do you get sed to treat the filename as a string instead of an input file? What command do I need to get "name.txt" as the output instead?
Drop the xargs and -0's.
find . -type f | sed 's/file//g'
This takes the output of find and sends it as input to sed.
I want to view for the files in /var/www the following data:
fullpath size mtime ctime md5
I ran the following command:
find /var/www/ -maxdepth 1 ! -type d -printf '%p\t%s\t%t\t%c\t' -exec md5sum {} \;
which gives me:
(fullpath size mtime ctime md5 fullpath)
/var/www/intranet/admin/tpl/view.tpl.php 1448 Wed Dec 16 18:51:06.0000000000 2015 Fri Sep 15 09:08:36.0805775786 2017 e0b7dacaf7c90fb0fbe7a69c331e36aa /var/www/intranet/admin/tpl/view.tpl.php
How can I filter the last fullpath?????? I do not want to show it. All fields are TAB separated.
I tried:
find /var/www/ -maxdepth 1 ! -type d -printf '%p\t%s\t%t\t%c\t'
-exec md5sum {} | awk '{print $1}'\;
for which I received the error: "find: missing argument to `-exec'"
find /var/www/ -maxdepth 1 ! -type d -printf '%p\t%s\t%t\t%c\t' -exec md5sum {} + | awk '{print $1}'
for which I got only the md5sum.
Thanks in advance!
Pipelines (|) are a shell-feature. To get shell features, one needs to invoke a shell:
find /var/www -maxdepth 1 ! -type d -printf '%p\t%s\t%t\t%c\t' -exec sh -c 'md5sum "$1" | awk '\''{print $1}'\' MD5 {} \;
Or, if you prefer commands spread over multiple lines:
find /var/www \
-maxdepth 1 \
! -type d \
-printf '%p\t%s\t%t\t%c\t' \
-exec sh -c 'md5sum "$1" | awk '\''{print $1}'\' MD5 {} \;
Notes
sh -c somestring invokes a shell and instructs it to execute whatever commands are in somestring.
sh -c somestring MD5 {} invokes the shell and executes somestring and assigns $0 to MD5 and $1 to whatever find substitutes for {}.
$0 is only used by the shell when it creates error messages and otherwise unimportant.
A complication is that our command, somestring, must contain both single quotes and double-quotes which is why we need escaped single-quotes.
In our case, we want somestring to be:
md5sum "$1" | awk '{print $1}'
To prevent the main shell from substituting in for $1, we need to put this inside single-quotes. However, we can't put single-quotes inside single-quotes. The workaround is to use this for our single-quoted string:
'md5sum "$1" | awk '\''{print $1}'\'
Lets say I hit foo.html with find, i would like to pipe the contents back into foo.html
find . -iregex '.*\(html\|htm\)' -printf '%P\0' | \
xargs -0 sed -Ee "s:(http|https)\://(www.|)${domain}[?/]::g" \
> # to what? {\} ???
Right now it does not know what or where its
Pass the -i flag to sed, then it will modify the input file in place.
find . -iregex '.*html?' -printf '%P\0' | xargs -0 sed -i -Ee "s:(http|https)\://(www.|)${domain}[?/]::g"
I'm trying to concatenate all the files of a that ends with coref extension.
This works (but add unwanted files):
find ../corpus/dev/txt/ | xargs cat
This not works.
find ../corpus/dev/txt/ -name '*.coref' | xargs cat
In the second comand find returns 1566 results but xrags cat does nothing.
Why the -name arguments mess it all?
Try to use -print0 like this:
find ../corpus/dev/txt/ -name '*.coref' -print0 | xargs -0 cat
if you find to many files and the xargs list gets too long, you can try this:
find ../corpus/dev/txt/ -name '*.coref' -print0 | xargs -n1 -0 cat >> /tmp/file